箭头函数没有自己的this,但是面试题涉及到箭头函数中的this,多数人还是会做错……
输出结果是什么?有几个this?
function foo() {
return () => {
return () => {
return () => {
console.log('id', this.id);
};
};
};
};
var f = foo.call({ id: 1 });
var t1 = f.call({ id: 2 })()();
var t2 = f().call({ id: 3 })();
var t3 = f()().call({ id: 4 });
all方法来调用函数,其中call的第一个参数,可以用来改变this的指向。var f=foo.call({id:1})含义是:调用foo,并把this的指向{id:1}。
分析:
整个代码,只有foo是普通的函数,而foo中返回的函数都是箭头函数。【图1】
因此只有foo中有this,而箭头函数没有自己的this,它里面的this要沿着作用域往外层查找【图2】
call的作用是调用函数,并改变this的指向,因此var f=foo.call( {id:1} )这句代码,就是调用foo,并把foo中的this指向{id:1} 【图3】
foo中使用return设置了返回值,所以变量f就是如下函数 【图4】
var t1=f.call( {id:2} )( )( )这句代码:
f.call( {id:2} )是调用【图四】中的函数,因此f.call( {id:2} )的值就是下图中选中的函数:【图5】
f.call({id:2})( )就是调用上图中返回的函数,f.call({id:2})( )的值如下:【图6】
f.call({id:2})( )( )就是继续调用上图中返回的函数,即执行 console.log(“id”,this.id)。通过图2可知,要沿着作用域往外查找this,所以最终的this就是foo中的this,因此会打印1:【图7】
而f.call({id:2}) 这句代码,虽然传了参数{id:2},但是f是箭头函数,没有this,所以call中的参数并不会起到作用。其余几句代码,同 var t1=f.call( {id:2} )()() 类似。
只要记住非箭头函数的this指向和在哪调用没关系,之和谁在调用有关;箭头函数没有自己的this,判断箭头函数的this指向就转化成通过函数作用域链向外层寻找的过程。
这个题里:
var f = foo.call( { id: 1 } ); // 是非箭头函数,它的this指向 { id: 1 }
其余 t1 到 t3 都是在 f 的基础上调用的,例如:var t1 = f.call( {id:2} )()()
他们都是箭头函数,又在 f 的内部,由箭头函数this指向和作用域链可快速判断,它们仨的this指向都是 f 的this指向。
代码中只有一个this,就是函数foo的this,
所以t1、t2、t3都输出同样的结果,
因为所有的内层函数都是箭头函数,都没有自己的this,
它们的this其实都是最外层foo函数的this。
所以本题只有一个this