看到有朋友在滴滴的面试题
var x = 1;
var kit = {
x:2,
buf:{
x:3,
fac(){
return this.x;
},
til: () => {
return this.x;
}
}
}
var foo0 = kit.buf.fac;
console.log(foo0());
console.log(kit.buf.fac());
console.log(kit.buf.til());
第一个 console 中执行的方法 foo0 是用 kit.buf.fac 赋值的,在调用时是在全局环境下执行的,this默认指向全局对象,所以第一个值是全局环境下声明的变量 x 的值 1;
第二个 console 中执行的方法 kit.buf.fac,是 kit.buf 调用该方法,this 指向 kit.buf,所以第二个值是 kit.buf 的属性 x 的值 3;
第三个 console 中执行的方法 kit.buf.til,涉及到箭头函数中 this 的指向问题
箭头函数不会创建自己的 this,它只会从自己的作用域链的上一层继承 this。
在箭头函数中,this 与封闭词法环境的 this 保持一致。
var ss = {
ss1:{
ss2:{
ss3:{
ss4:() => { console.log(this == window) }
}
}
}
}
ss.ss1.ss2.ss3.ss4();
// 居然输出的是 true,也就是说这里的 this 是指向 window 的
本着箭头函数 this 指向外层作用域的原则,ss.ss1.ss2.ss3.ss4中箭头函数外部的作用域是全局作用域,所以指向全局对象 window
// 创建一个含有bar方法的obj对象,
// bar返回一个函数,
// 这个函数返回this,
// 这个返回的函数是以箭头函数创建的,
// 所以它的this被永久绑定到了它外层函数的this。
// bar的值可以在调用中设置,这反过来又设置了返回函数的值。
var obj = {
bar: function() {
var x = (() => this);
return x;
}
};
// 作为obj对象的一个方法来调用bar,把它的this绑定到obj。
// 将返回的函数的引用赋值给fn。
var fn = obj.bar();
// 直接调用fn而不设置this,
// 通常(即不使用箭头函数的情况)默认为全局对象
// 若在严格模式则为undefined
console.log(fn() === obj); // true
// 但是注意,如果你只是引用obj的方法,
// 而没有调用它
var fn2 = obj.bar;
// 那么调用箭头函数后,this指向window,因为它从 bar 继承了this。
console.log(fn2()() == window); // true
在上面的例子中,一个赋值给了 obj.bar的函数(称为匿名函数 A),返回了另一个箭头函数(称为匿名函数 B)。因此,在 A
调用时,函数B的this被永久设置为obj.bar(函数A)的this。当返回的函数(函数B)被调用时,它this始终是最初设置的。在上面的代码示例中,函数B的this被设置为函数A的this,即obj,所以即使被调用的方式通常将其设置为 undefined 或全局对象(或者如前面示例中的其他全局执行环境中的方法),它的 this 也仍然是 obj 。
也就是说第三个 console 中的 this 指向的是 window 这个全局对象
关于this这里还有另外一个题目 关于this、let、var的题目(一) 可以看看