标签:
You don‘t know JavaScript是github上一个系列文章 
 
初看到这一标题的时候,感觉怎么老外也搞标题党,用这种冲突性比较强的题目吸引眼球,以致最初真没去看内容。直到出了中文版《你不知道的JavaScript》,一看评价大家都说好,买来一读,内容果然很好,很多地方,让我这个半路转行JavaScript的人豁然开朗。中文版现在出了上卷,中卷应该很快会推出,下卷就要等久一点了
1.现代JavaScript已经不再是解释执行的,而是编译执行的。但是与传统的编译语言不同,它不是提前编译,编译结果不能进行移植。编译过程中,同样会经过分词/词法分析,解析/语法分析,代码生成三个阶段。
2.以var a = 2;语句为例,对这一程序语句对处理,需要经过引擎,编译器,作用域三者的配合。其中,引擎从头到尾负责整个javascript程序的编译和执行过程;编译器负责语法分析和代码生成;作用域负责收集并维护由所有声明的标识符组成的系列查询,并实施一套规则,确定当前执行的代码对这些标识符的访问权限。
3.对于var a = 2;编译器首先查找作用域中是否已经有该名称的变量,然后引擎中执行编译器生成的代码时,会首先查找作用域。如果找到就执行赋值操作,否则就抛出异常
4.引擎对变量的查找有两种:LHS查询和RHS查询。当变量出现中赋值操作左侧时是LHS查询,出现中右侧是RHS查询
1.词法作用域就是定义在词法阶段的作用域。词法作用域是由你在写代码时将变量和块作用域写在哪里决定的,词法处理器分析代码时会保持作用域不变
function foo(a){ 
    var b = a * 2; 
    function bar(c){ 
        console.log(a,b,c); 
    } 
    bar(b * 3); 
} 
foo(2);     

(function fun(){})() 1.如下示例
a=2; var a; console.log(a);
上述代码输出的不是undefined,而是2。因为上述代码需要经过编译器的编译,编译过程中首先会进行变量声明,然后再由引擎进行变量赋值,所以,上述变量声明虽然写在第二行,但是声明过程是首先执行的
console.log(a); var a = 2;
foo(); 
function foo(){ 
    console.log(a);//undefined 
    var a = 2; 
}
1.词法作用域是一套引擎如何寻找变量以及会在何处找到变量的规则。词法作用域最重要的特征是它的定义过程发生中代码的书写阶段
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 
    } 
)
本节为觉得书中写的有点绕,不清晰。推荐阅读