JavaScript只有Lexical Scope 模式
Lexical Scope就是在写代码的时候,定义函数的时候创建的作用域!
而动态作用域是在runtime时,函数被调用的地方的作用域!
实际上 dynamic Scope是 this关键字的近亲。这会在this & Object Prototypes系列讲解。
第二章,lexical scope是这方面的法则:Engine如何查询一个变量,在哪找到这个变量!
关键特征就是lexical scope是定义在author-time,打代码的阶段。(并不使用eval())
最后: this关键字关心一个函数如何被调用,这证明了this机制和动态作用域的相关性!
Lexical-this
ES6提供了一个句法:关于函数声明的句法。arrow function. 也称fat arrow.
var foo = a => { console.log( a ); }; foo( 2 ); // 2
这样就可以省略function关键字。
但是!!!你理解箭头函数中的this的绑定原则吗?
看这个案例:
var obj = {
id: "awesome",
cool: function coolFn() {
console.log( this.id );
}
};
var id = "not awesome";
obj.cool(); // awesome
setTimeout( obj.cool, 100 ); // not awesome 这是怎么回事???
?的案例, 调用setTimeout方法的是window对象。
省略window.setTimeout(函数, 时间)的window, 那么默认this就是window.
所以,执行obj.cool。代码中的this其实是window对象。
即this是根据调用方法的对象来绑定的!!!
解决办法是,var self = this;
在代码中预先设定好!!这就是Lexical - this,在编写代码的时候,就把this固定死!!
而ES6中的箭头函数,就是这个行为机制。Lexical- this。
var obj = { count: 0, cool: function coolFn() { if (this.count < 1) { setTimeout( () => { // arrow-function ftw? this.count++; console.log( "awesome?" ); }, 100 ); } } }; obj.cool(); // awesome?
this不再是根据平常的调用方法的对象来绑定,而是根据Lexical-this。
原文: take on the this
value of their immediate lexical enclosing scope
this.count中的this就是cooFn函数作用域。
箭头函数仅仅继承了 cool()函数的绑定!
cool()函数的绑定,就是obj对象!!!
作者使用这个方法,代替箭头函数,React中常用bind.绑定传入的prop数据。
var obj = { count: 0, cool: function coolFn() { if (this.count < 1) { setTimeout( function timer(){ this.count++; // `this` is safe because of `bind(..)` console.log( "more awesome" ); }.bind( this ), 100 ); // look, `bind()`! } } }; obj.cool(); // more awesome