为何原型函数未使用正确的this指向?ES6原型继承疑问
解决JS原型继承中this指向window的问题
嘿,我来帮你拆解这个this指向的坑!你遇到的问题其实是JS里this绑定的经典误区,核心在于你定义方法的方式不同,导致this的指向天差地别。
为什么introduce()和friends()能正常工作?
大概率你的代码里,这两个方法是直接在MarvelHero构造函数中挂载到实例上的普通函数,比如:
function MarvelHero(name) { this.name = name; // 实例方法:直接绑定到this(实例对象) this.introduce = function() { console.log(`我是${this.name}`); }; this.friends = function() { console.log(`${this.name}的朋友们...`); }; }
当你调用ironman.introduce()时,this会自动绑定到调用这个方法的对象(也就是ironman实例),所以能正确读取到实例上的name属性。
为什么villain()和summarize()会指向window?
最可能的原因是你用箭头函数在原型上定义了这两个方法,比如:
// 错误示范:原型上用箭头函数 MarvelHero.prototype.villain = () => { console.log(`${this.name}的反派是灭霸`); };
箭头函数的this是词法绑定的——它不会根据调用方式改变指向,而是继承定义时所在作用域的this。在全局作用域下定义原型上的箭头函数,this会直接绑定到window对象,所以哪怕你用ironman.villain()调用,this依然是window,自然读不到实例的name。
另一种小概率情况是继承时没正确调用父类构造函数(比如子类没写MarvelHero.call(this, name)),但这种情况this会指向实例,只是name属性不存在,而不是指向window,所以箭头函数的可能性更大。
解决方法
把原型上的方法改成普通函数表达式就行:
// 正确写法:原型上用普通函数 MarvelHero.prototype.villain = function() { console.log(`${this.name}的反派是灭霸`); };
这样调用ironman.villain()时,this会自动绑定到调用它的实例对象,就能正确读取name了。
如果用ES6的class语法,记得用普通方法定义(不要用箭头函数):
class MarvelHero { constructor(name) { this.name = name; } // 普通class方法,this自动绑定到实例 introduce() { console.log(`我是${this.name}`); } villain() { console.log(`${this.name}的反派是灭霸`); } }
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

