你不知道的Javascript(上卷)读书笔记之二 ---- 词法作用域
在前一篇文章中,我们把作用域定义为”管理、维护变量的一套规则”,接下来是时候来深入讨论一下Js的作用域问题了,首先我们要知道作用域一般有两种主要的工作类型,一种是词法作用域,一种是动态作用域, Javascript采用的是词法作用域, 关于动态作用域的有兴趣的可以自行Google。
1.词法阶段
首先我们要理解”词法阶段”这个词语,我们已经了解到Js存在一个编译阶段,编译阶段的第一步就是分词/词法分析,我们可以简称为”词法阶段”
简单来说,词法作用域就是定义在词法阶段的作用域,词法作用域是你在写代码时把变量和块作用域写在哪里来决定的,词法分析器处理代码后,在大部分情况下会保持作用域不变。我们需要注意以下几点:
a.当引擎需要查询变量时,总是从当前作用域开始查找
b.作用域查找会在找到第一个匹配的标识符时停止
c.遮蔽效益(内部的标识符”遮蔽”了外部的标识符)
d.全局变量会自动成为全局对象的属性,通过这种技术可以间接的访问那些被遮蔽的全局变量
e.无论函数在哪里被调用,也无论它如何被调用,它的词法作用域也只由它被声明的位置决定
f.词法作用域之会查找一级标识符,比如a、b、c。如果代码中引用了foo.bar.baz,词法作用域只会试图查找foo标识符,然后在使用对象属性访问规则进行对bar以及baz的访问
2.欺骗词法
我们有时可以使用一些语句对词法作用域进行欺骗,但是要注意的一点:欺骗词法作用域会导致性能下降
2.1 eval()
eval() 接受一个字符串参数,将这段字符串视作Javascript执行
在严格模式下,eval()中的代码有自己的词法作用域,因此其中的声明无法修改作用域外的代码的效果,而在非严格模式下,eval()中的代码可以修改eval()方法所在的作用域,即eval()方法中的所有声明与eval()方法处于同一个词法作用域,因而可以修改最终的效果。
new Function(...) 类似,将对传入的字符串动态生成函数,因此不作过多阐述。
2.2 with()
with(obj){ … } 实质上是创建了或者指向了obj中的词法作用域,在这个作用域中,所有的声明在被引擎执行时,都会在这个作用域中查找,如果查找不到,会在obj的上一层作用域继续查找,但是,当如果一直到顶层的全局作用域还没有找到时,会创建一个全局变量。并且,with在严格模式下被完全禁止运行。
2.3 性能
eval() 和 with() 会在运行时修改或创建作用域,以此来欺骗其他词法作用域。但是会极大的降低代码的运行效率,有可能之前对代码进行的优化会全部无效,使得代码的运行变得很慢。
你不知道的Javascript(上卷)读书笔记之二 ---- 词法作用域的更多相关文章
- JS闭包—你不知道的JavaScript上卷读书笔记(二)
关于闭包,初学者会被绕的晕头转向,在学习的路上也付出了很多精力来理解. 让我们一起来揭开闭包神秘的面纱. 闭包晦涩的定义 看过很多关于闭包的定义,很多讲的云里雾里,晦涩难懂.让不少人以为闭包是多么玄乎 ...
- JavaScript词法作用域—你不知道的JavaScript上卷读书笔记(一)
前段时间在每天往返的地铁上抽空将 <你不知道的JavaScript(上卷)>读了一遍,这本书很多部分写的很是精妙,对于接触前端时间不太久的人来说,就好像是叩开了JavaScript的另一扇 ...
- 《你不知道的JavaScript》读书笔记(二)词法作用域
JavaScript 采用的是 词法作用域 的工作模型. 定义 词法化:大部分标准语言编译器的第一个工作阶段叫词法化(单词化),这个过程会对源代码中的字符进行检查,如果是有状态的解析过程,还会赋予单词 ...
- JavaScript中的对象与原型—你不知道的JavaScript上卷读书笔记(四)
一.对象 对象可以通过两种形式定义:声明(文字)形式和构造形式.即: var myObj = { key: value // ... }; 或: var myObj = new Object(); m ...
- JavaScript中的this—你不知道的JavaScript上卷读书笔记(三)
this是什么? this 是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件.this 的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式.当一个函数被调用时,会 ...
- 你不知道的javascript 上卷 读书笔记
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 《你不知道的JavaScript》读书笔记(一)作用域
名词 引擎:从头到尾负责整个 JavaScript 程序的 编译 及 执行 过程. 编译器:负责 语法分析 及 代码生成. 作用域:负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套 ...
- 《你不知道的javascript》读书笔记2
概述 放假读完了<你不知道的javascript>上篇,学到了很多东西,记录下来,供以后开发时参考,相信对其他人也有用. 这篇笔记是这本书的下半部分,上半部分请见<你不知道的java ...
- 《你不知道的javascript》读书笔记1
概述 放假读完了<你不知道的javascript>上篇,学到了很多东西,记录下来,供以后开发时参考,相信对其他人也有用. js的工作原理 引擎:从头到尾负责整个js的编译和运行.(很大一部 ...
随机推荐
- JAVA collection集合之 扑克牌游戏
主要内容:这里使用collection集合,模拟香港电影中大佬们玩的扑克牌游戏. 1.游戏规则:两个玩家每人手中发两张牌,进行比较.比较每个玩家手中牌最大的点数,大小由A-2,点数大者获胜.如果点数相 ...
- Java中2+2==5解读
先来看一段程序,如下: package basic; import java.lang.reflect.Field; public class TestField { public static vo ...
- [转载] php用csv文件导出大量数据
header ( "Content-type:application/vnd.ms-excel" ); header ( "Content-Disposition:fil ...
- 【夯实PHP基础系列】linux下yum安装PHP APC
Alternative PHP Cache(可选PHP缓存),依赖于 PECL扩展库 用源码方式安装,直接yum就行了:首先要安装apc的依赖包:yum install php-pear php-de ...
- 9、ASP.NET MVC入门到精通——Controller(控制器)
本系列目录:ASP.NET MVC4入门到精通系列目录汇总 Controller主要负责响应用户的输入.主要关注的是应用程序流,输入数据的处理,以及对相关视图(View)输出数据的提供. 继承自:Sy ...
- struts的声明式异常处理
情景 使用Struts封装的下载文件的功能 当下载文件找不到的时候,struts获取的InputStream为null 这个时候,就会报500错误 java.lang.IllegalArgumentE ...
- MVC的增删改查
基本都要使用C控制器中的两个action来完成操作,一个用于从主界面跳转到新页面.同时将所需操作的数据传到新界面,另一个则对应新界面的按钮,用于完成操作.将数据传回主界面以及跳转回主界面.根据不同情况 ...
- [C/C++] DebugBreak
在代码中直接调用DebugBreak()函数,可以使程序中断运行,和在IDE中设置断点中断运行的道理是一样的. 用这种方式,一些情况下比打断点更方便调试,如下,在test()函数返回0时激活断点 #i ...
- JS中用new创建对象与不用new创建对象区别:
function classA() { console.log(this); var that = this == window ? {} : this; that.name = "clas ...
- iOS---用Application Loader 上传的时候报错No suitable application records were found. Verify your bundle identifier 'xx' is correct
用Application Loader 上传的时候报错,突然发现用Application Loader的账号 竟然不是公司的账号 换成公司的账号 就可以了.