对于这个结论,其实要分情况讨论。
- 当在class定义方法使用箭头函数的时候,在其定义的时候已经决定.
class Temp {
constructor() {
this.name = 'tariz';
}
getNameArrow = () => {
console.log(this.name);
}
getName() {
console.log(this.name);
};
};
上述代码通过babel转换以后
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
class Temp {
constructor() {
_defineProperty(this, "getNameArrow", () => {
console.log(this.name);
});
this.name = "tariz";
}
getName() {
console.log(this.name);
}
}
我们会发现使用箭头函数定义类的方法的时候,其实在当前方法绑定在this属性上,当我们不主动采用call、bind、apply改变this指向的时候,无论如何调用getNameArrow方法,this都指向该类的实例。
- 如果不在上述1的情况下,使用箭头函数,箭头函数的this指向取决于定义时上一层执行上下文的this(可能表达不够清晰),我们直接看如下代码进行分析。
const obj = {
name: 'tariz',
getName: () => {
console.log(this.name);
}
};
console.log(obj.getName()); // undefined
babel转换以后
var _this = this;
var obj = {
name: "tariz",
getName: function getName() {
console.log(_this.name);
}
};
上述代码输出值为undefined,这个结果并不让人意外,接下来我会通过chrome浏览器调试解释。
结合第二点的结论,指向上一层执行上下文的this,当前getName上层执行上下文即最开始调用匿名函数(此时this为window),所以getName的this指向为window,window上并没有这个属性,所以为undefined。
接下来我们再用一个例子进一步分析。
const obj = {
name: 'tariz',
getName() {
const showMyName = () => {
console.log(this.name);
};
showMyName();
}
};
const showMyNameWrapper = obj.getName;
obj.getName(); // tariz
showMyNameWrapper(); // undefined
在上述这个例子中,showMyName函数中this的指向取决于getName函数的执行上下文的this,但是getName函数执行上下文是不稳定的,在其执行动态决定的。
在obj.getName()中,getName函数执行上下文中this为obj,所以showMyName中打印结果为tariz。
在showMyNameWrapper中,getName函数执行上下中的this为window,应为当前getName在全局下调用,所以其值为undefined;
function Parent(s) {
s();
};
const obj = {
name: 'egg',
getName: function () {
new Parent(() => { console.log('parent', this.name) });
setTimeout(() => { console.log('time:', this.name) });
console.log(this.name);
const add = () => { console.log(this.name) };
add();
}
};
obj.getName();
// parent egg
// egg
// egg
// time: egg
babel编译箭头函数:
function Parent(s) {
s();
}
var obj = {
name: "egg",
getName: function getName() {
var _this = this;
new Parent(function () {
console.log("parent", _this.name);
});
setTimeout(function () {
console.log("time:", _this.name);
});
console.log(this.name);
var add = function add() {
console.log(_this.name);
};
add();
}
};
obj.getName();
// 此时的this已经被确定为getName执行上下文的this
以上代码比之前例子复杂,通过chrome调试来进行分析。
当执行到创建Parent实例的时候,执行箭头函数的时候,我们发现当前函数调用栈为4个,其中红色箭头指向的匿名函数为当前的箭头函数,虽然上一层执行上下文为Parent,但是箭头函数执行在其定义已确定this指向即上面的猜想,所有this依旧指向getName执行上下文的this,也就是obj。
同理setTimeout也发生类似的转换。所以this也执行getName执行上下文的this,这个过程就不重复解释,有兴趣可以调试。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!