You don't know JavaScript是github上一个系列文章
初看到这一标题的时候,感受怎么老外也搞标题党,用这种冲突性比较强的题目吸引眼球,以至最初真没去看内容。直到出了中文版《你不知道的JavaScript》,一看评价你们都说好,买来一读,内容果真很好,不少地方,让我这个半路转行JavaScript的人豁然开朗。中文版如今出了上卷,中卷应该很快会推出,下卷就要等久一点了javascript
1.现代JavaScript已经再也不是解释执行的,而是编译执行的。可是与传统的编译语言不一样,它不是提早编译,编译结果不能进行移植。编译过程当中,一样会通过分词/词法分析,解析/语法分析,代码生成三个阶段。html
2.以var a = 2;语句为例,对这一程序语句对处理,须要通过引擎,编译器,做用域三者的配合。其中,引擎从头至尾负责整个javascript程序的编译和执行过程;编译器负责语法分析和代码生成;做用域负责收集并维护由全部声明的标识符组成的系列查询,并实施一套规则,肯定当前执行的代码对这些标识符的访问权限。java
3.对于var a = 2;编译器首先查找做用域中是否已经有该名称的变量,而后引擎中执行编译器生成的代码时,会首先查找做用域。若是找到就执行赋值操做,不然就抛出异常git
4.引擎对变量的查找有两种:LHS查询和RHS查询。当变量出现中赋值操做左侧时是LHS查询,出现中右侧是RHS查询es6
1.词法做用域就是定义在词法阶段的做用域。词法做用域是由你在写代码时将变量和块做用域写在哪里决定的,词法处理器分析代码时会保持做用域不变github
function foo(a){ var b = a * 2; function bar(c){ console.log(a,b,c); } bar(b * 3); } foo(2);
(function fun(){})()
1.以下示例 web
a=2; var a; console.log(a);
上述代码输出的不是undefined,而是2。由于上述代码须要通过编译器的编译,编译过程当中首先会进行变量声明,而后再由引擎进行变量赋值,因此,上述变量声明虽然写在第二行,可是声明过程是首先执行的ajax
console.log(a); var a = 2;
foo(); function foo(){ console.log(a);//undefined var a = 2; }
1.词法做用域是一套引擎如何寻找变量以及会在何处找到变量的规则。词法做用域最重要的特征是它的定义过程发生中代码的书写阶段segmentfault
2.动态做用域让做用域做为一个在运行时就被动态肯定的形式,而不是在写代码时进行静态肯定的形式。设计模式
function foo(){ console.log(a);//2 } function bar(){ var a = 3; foo(); } var a = 2; bar();
词法做用域让foo()中的a经过RHS引用到了全局做用域中的a,因此输出2;动态做用域不关心函数和做用域如何声明以及在何处声明,只关心从何处调用。换言之,做用域链是基于调用栈的,而不是代码中的做用域嵌套。若是以动态做用域来看,上面代码中执行时会输出3
3.JavaScript不具有动态做用域,可是this机制中某种程度上很像动态做用域,this关注函数如何调用。
var obj = { msg : 'awesome', cool:function(){ setTimeout(function timer(){ console.log(this.msg); },100); } }; var msg = 'not awesome'; obj.cool(); //not awesome var obj = { msg : 'awesome', cool:function(){ var self = this; setTimeout(function timer( console.log(self.msg); },100); } }; var msg = 'not awesome'; obj.cool(); //awesome var obj = { msg : 'awesome', cool:function(){ setTimeout(() => { console.log(this.msg); },100); } }; var msg = 'not awesome'; obj.cool(); //awesome var obj = { msg : 'awesome', cool:function(){ setTimeout(function timer() { console.log(this.msg); }.bind(this),100); } }; var msg = 'not awesome'; obj.cool(); //awesome
function foo(){ console.log(this.a); } var a = 2; foo();//2
function foo(){ console.log(this.a); } var obj={ a:2, foo:foo }; obj.foo();//2
var obj = {}; Object.defineProperty( obj, "a", { value:2, writable:true, configurable:true, enumerable:true } ); obj.a;//2
var obj = { this._a_ = 2; get a(){ return this._a_; }, set a(val){ this._a_ = val * 2; } }; Object.defineProperty( obj, "b", { get:function(){return this._a_ * 2}, enumerable:true } )
本节为以为书中写的有点绕,不清晰。推荐阅读