this小测试
下面的这段代码,this指向哪里?
var obj = {
    a: function() {
        console.log(this);
    }
}
var b = obj.a;
b();结果是this指向window。
一般的,this指向函数运行(调用)时所在的执行环境【《JavaScript高级程序设计》4.2节执行环境及作用域】的(变量)对象(简单地,this指向函数的调用者)
解析
var b = obj.a; // ==>相当于
var b = function() {
console.log(this);
}
函数调用时(b();)其所在的执行环境是全局环境,所以this指向全局变量对象window
ES6箭头函数
例1【阮一峰《ECMAScript 6 入门》-7.函数的扩展:箭头函数】
我将阮老师的例子代码修改了一下:
(普通函数)
function foo() {
    console.log("id1:", this.id);
    console.log("this1:", this);
    setTimeout(function() {
        console.log("id2:", this.id);
        console.log("this2:", this);
    }, 0);
}
var id = 21;
foo();
// Chrome
// id1: 21
// this1: window
// id2: 21
// this2: window
foo.call({id: 42});
// Chrome
// id1: 42
// this1: {id: 42}
// id2: 21
// this2: window注意:超时调用(setTimeout回调)的代码都是在全局作用域环境中执行的,因此(setTimeout回调)函数中this的值在非严格模式下指向window对象,在严格模式下是undefined
例如
var obj = {
    console.log(this);
    setTimeout(function() {
        console.log(this);
    }, 0);
}
obj.a();
// Chrome
// {a: f}
// window我们使用foo函数的call方法改变了foo函数调用时函数体内this的指向({id: 42}这个对象),但setTimeout回调函数中的this依旧指向window对象(因为在全局环境中运行)。
接下来再将例1改写一下,将foo函数中的setTimeout回调函数改成箭头函数的形式:
例2
(箭头函数)
function foo() {
    console.log("id1:", this.id);
    console.log("this1:", this);
    setTimeout(() => {
        console.log("id2:", this.id);
        console.log("this2:", this);
    }, 0);
}
var id = 21;
foo();
// Chrome
// id1: 21
// this1: window
// id2: 21
// this2: window
foo.call({id: 42});
// Chrome
// id1: 42
// this1: {id: 42}
// id2: 42
// this2: {id: 42}foo();的输出结果没有变化,但foo.call({id: 42});的输出结果改变了。
到底发生了什么?
在这里直接给出结论:
箭头函数根本没有自己的this,导致内部的this指向了外层代码的this,这个指向在定义时就已经确定而不会在调用时指向其执行环境的(变量)对象。
注意:因为箭头函数内部的this是指向外层代码块的this(最近的this,例2中的foo函数)的,所以我们可以通过改变外层代码块的this的指向从而改变箭头函数中this的指向(例2中使用了foo函数的call方法)。
重新解释例2
因为箭头函数(setTimeout回调)没有自己的this,导致其内部的this引用了外层代码块的this,即foo函数的this,
(要注意:在定义阶段(调用函数前),foo函数的this的值并不确定【《JavaScript高级程序设计》第三版5.5.4函数内部属性】,但箭头函数的this自定义阶段开始就指向foo函数的this了)
又因为使用call方法改变了foo函数运行(调用)时其函数体内this的指向(重新指向对象{id: 42})从而使箭头函数中this的指向发生变化,最后输出例2所示结果。










