《你不知道的JavaScript》笔记(一)
用了一个星期把《你不知道的JavaScript》看完了,但是留下了很多疑惑,于是又带着这些疑惑回头看JavaScript的内容,略有所获。
第二遍阅读这本书,希望自己能够有更为深刻的理解。
词法作用域
……如果是 有状态 的解析过程,还会赋予单词语义……
这本书是以编译原理的部份内容结合JavaScript来开篇的,所以如果没有学过编译原理,这一小部分内容显得有些晦涩。
虽然多数人没有接触过编译原理,但有一个东西必定知道,就是markdown语法。实际上,从markdown文件到HTML的过程就包含了词法化的过程。
那什么是有状态?粗略来讲,就是一个模式匹配的问题,或者可以认为是字符串的匹配:
源串:"str782yui"
,待匹配的串:"sj1"
,思考一下朴素匹配的算法,我们是要从头开始比较的,那么在每一次比较的时候,就两种状态,字符相同/不相同,每接受一个字符,就会走向其中一个状态。
这就是所谓的状态。当然了,这也只是一种粗浅的比喻,可能会有更好的。
说句心里话,编译原理是很有用的科目,但是真正学起来的时候还是挺痛苦的。
考虑以下代码:
function foo(a) { var b = a*2; function bar(c) { console.log(a, b, c); } bar(b*3); } foo(2);
在这个例子中有三个逐级 嵌套的作用域……
对于java程序员来说,一对花括号就可以限制变量的作用域,而且作用域之间的关系有 同级 和 父子级 两种,同时还有包(package)这种很方便的东西。
但是JavaScript就不一样了,一对花括号是不能定义一个作用域的,而且由于var声明的变量存在变量提升,所以有些时候我们会发现某个变量并不能像预期的那样被约束在某对花括号中,于是就出现很多经典的问题。
JavaScript中函数和catch子块是能够创建作用域的,但是个人认为,为了创建一个作用域而使用catch子块,这等于是给catch增加了一个语义,二义性不好说,这可能会使程序变得不好阅读。但大家都这么做的话,那我也就随大流吧。
想起一个不知道从哪里传出来的笑话,说:catch不是异常处理关键字,而是流程控制语句。
提到了作用域,就一定要提变量的屏蔽,简单来说就一句话: 内部作用域的变量会屏蔽外部作用域的同名变量。
那可能就有人问了,(上述代码)我通过foo.b
这种方式能不能访问呢?
……想啥呢?想对象了是吧?不过可以通过window.foo
这种方式来访问全局变量foo,为啥?这window
不是一个全局的对象嘛,所有的全局变量都会自动的成为全局对象的属性。
……词法作用域查找 只会 查找一级标识符……
这句话就是在回答上面我提出来的问题。
function foo(str, a) { eval(str); console.log(a, b); } var b = 2; foo("var b = 3", 1);
eval(..)
调用中的"var b = 3;
"这段diamante会被当做本来就在哪里一样处理……
这话说的好拗口啊?
有时候写程序的时候,我就会想,哎呀,要是能把一个字符串变成一个变量就好了,多方便啊。
eval差不多就是在完成这件事。书上说的这么绕,可能是为了可以让读者更好的理解。
在我看来,eval函数所做的就是动态的生成一段代码,插入到对应的位置上,变成了另一个程序,照此执行。
with声明实际上是根据你传递给它的对象凭空创建了一个 全新的词法作用域。
到这里又增加了一个能够创建作用域的关键字。
var obj = {
a: 1
};
with(obj) {
a = 2;
b = 3;
};
对上述代码,我们可以这么理解,with将obj声明为一个作用域,with内部的语句都是在这个作用域中的,so……
eval(..)和with会在运行时修改或创建新的作用域,以此来欺骗其他书写时定义的词法作用域。
eval是修改,with是创建作用域。
这两个都会导致程序性能的下降,原因是影响了编译优化,其实这俩就像是一个开关,任意一个存在时,都会打开禁止编译优化的按钮。就像是所谓的禁止指令重排一样。
总结
|ू・ω・` ):这本书真好看。
《你不知道的JavaScript》笔记(一)的更多相关文章
- python程序设计语言笔记 第一部分 程序设计基础
1.1.1中央处理器(CPU) cpu是计算机的大脑,它从内存中获取指令然后执行这些指令,CPU通常由控制单元和逻辑单元组成. 控制单元用来控制和协调除cpu之外的其他组件的动作. 算数单元用来完成数 ...
- C程序设计语言笔记-第一章
The C Programming language notes 一 基础变量类型.运算符和判断循环 char 字符型 character ...
- 北京大学Cousera学习笔记--6-计算导论与C语言基础--计算机的基本原理-认识程序设计语言 如何学习
1.是一门高级程序语言 低级语言-机器语言(二进制) 汇编语言-load add save mult 高级语言:有利于人们编写理解 2.C语言的规范定义非常的宽泛 1.long型数据长度不短于int型 ...
- MOOC 编译原理笔记(一):编译原理概述以及程序设计语言的定义
编译原理概述 什么是编译程序 编译程序指:把某一种高级语言程序等价地转换成另一张低级语言程序(如汇编语言或机器代码)的程序. 高级语言程序-翻译->机器语言程序-运行->结果. 其中编译程 ...
- 20145213《Java程序设计学习笔记》第六周学习总结
20145213<Java程序设计学习笔记>第六周学习总结 说在前面的话 上篇博客中娄老师指出我因为数据结构基础薄弱,才导致对第九章内容浅尝遏止地认知.在这里我还要自我批评一下,其实我事后 ...
- javascript高级程序设计阅读笔记(一)
javascript高级程序设计阅读笔记(一) 工作之余开发些web应用作为兴趣,在交互方面需要掌握javascript和css.HTML5等技术,因此读书笔记是必要的. javascript简介 J ...
- 《c++程序设计》笔记
本文是学习谭浩强老师的<c++程序设计>后的笔记. 1.概述 c++是贝尔实验室在c语言的基础上发展而来,与c兼容.用c语言写的程序可以不加修改用于c++.从c++的名字可以看出它是c的超 ...
- 003-scanf函数使用和表达式-C语言笔记
003-scanf函数使用和表达式-C语言笔记 学习目标 1.[掌握]输入函数scanf的基本使用方法 2.[掌握]输入函数scanf运行原理和缓冲区理解 3.[掌握]算术运算符和算术表达式的使用 4 ...
- 操作系统和程序设计语言的API使用的字符编码分析
1.Java的运行环境中,String是什么编码? 使用java做程序设计语言,字符编码是和jvm相关的,和操作系统无关. java默认的编码是jvm在安装的时候就确定了的,它是根据你的系统的环境确 ...
- 扩展《C程序设计语言》练习2-3程序通用性
最近开始自学C语言,在看K&R的<C程序设计语言>.练习2-3要求写一个函数,将输入的十六进制数字字符串转换成与之等价的整数值,配套答案没有扩展程序的通用性,所以我就稍微改造改造. ...
随机推荐
- JavaScript 数据结构与算法之美 - 归并排序、快速排序、希尔排序、堆排序
1. 前言 算法为王. 想学好前端,先练好内功,只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算 ...
- Keras(二)Application中五款已训练模型、VGG16框架解读
Application的五款已训练模型 + H5py简述 Keras的应用模块Application提供了带有预训练权重的Keras模型,这些模型可以用来进行预测.特征提取和finetune. 后续还 ...
- NLP(十九) 双向LSTM情感分类模型
使用IMDB情绪数据来比较CNN和RNN两种方法,预处理与上节相同 from __future__ import print_function import numpy as np import pa ...
- JavaScript入门之AJAX:原生ajax
背景 传统的Web应用允许用户端填写表单(form),当提交表单时就向网页服务器发送一个请求.服务器接收并处理传来的表单,然后送回一个新的网页,但这个做法浪费了许多带宽,因为在前后两个页面中的大部分H ...
- HDU-4725 The Shortest Path in Nya Graph (拆点+dji)
HDU 4725 The Shortest Path in Nya Graph : http://acm.hdu.edu.cn/showproblem.php?pid=4725 题意: 在一个图中跑最 ...
- poj 2649 Factovisors 对n!进行因数分解
Factovisors Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4431 Accepted: 1086 Descr ...
- Mysql相关:navicat for mysql 加注释
在 navicat 中有三种注释的书写方式: 以 # 开头的字符串,可以多个 # 连续以 – 开头的字符串,注意:只能是 – ,而且 – 后面需要加一个半角空格以 /* */ 包围的字符串,类似于 J ...
- react页面内嵌微信二维码 和 自定义样式 以及 微信网页共用unionId问题
在react页面内嵌“微信二维码”,实现PC端通过微信扫码进行登录.首先去微信开放平台注册一个账号,创建一个网站应用,提交网站备案审核,获取appid和appsecret:其他开发流程根据微信文档来进 ...
- 简单粗暴详细讲解javascript实现函数柯里化
函数柯里化(黑人问号脸)???Currying(黑人问号脸)???妥妥的中式翻译既视感:下面来一起看看究竟什么是函数柯里化: 维基百科的解释是:把接收多个参数的函数变换成接收一个单一参数(最初函数的第 ...
- 一步一步搞安卓开发(AndroidStudio)
一.前言 好长时间没做过Android应用开发了,由于工作需要,又要开始做这一块了.记得之前都是用Eclipse+ADT+ADK来开发的,官网上下载个adt-bundle就可以了,现在官方已经不更新了 ...