You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何JavaScript原型继承中首次调用getTitle()返回undefined?

问题解析:首次调用getTitle()返回undefined,第二次“正常”的原因

核心问题出在你用箭头函数定义原型方法上,箭头函数的this绑定规则和普通函数完全不同:

  • 箭头函数没有独立的this,它的this是在定义时就绑定好的,指向定义它时所在上下文的this。在这里,所有原型方法都定义在全局作用域,所以this指向全局对象(浏览器是window,Node.js是globalThis),而不是调用方法的实例对象。

具体执行过程:

  1. 首次调用engineerObject.getTitle():
    箭头函数里的this是全局对象,全局对象上没有title属性,所以返回undefined。

  2. 调用engineerObject.setTitle('Manager')后:
    同样因为是箭头函数,this指向全局对象,这行代码实际上是给全局对象添加了title属性并赋值为'Manager'。第二次调用getTitle()时,读取的是全局对象的title,所以返回'Manager'——看起来正常,但本质是操作了全局变量,不是实例的属性,属于隐性bug。

修复方案:

把所有原型方法的箭头函数改成普通函数,普通函数作为方法调用时,this会自动指向调用它的实例对象:

function Employee(title) {
    this.title = title;
}
// 替换箭头函数为普通函数
Employee.prototype.setTitle = function(title) {
    this.title = title;
};
Employee.prototype.getTitle = function() {
    return this.title;
};

function Engineer(title, isManager) {
    Employee.call(this, title);
    this.isManager = isManager;
}
Object.setPrototypeOf(Engineer.prototype, Employee.prototype);

// 同样替换为普通函数
Engineer.prototype.setIsManager = function(isManager) {
    this.isManager = isManager;
};
Engineer.prototype.getIsManager = function() {
    return this.isManager;
};

function main() {
    const engineerObject = new Engineer('Developer', false);
    
    console.log(`Initial Employee Profile - Title is ${engineerObject.getTitle()}.`)
    // 现在会正确返回'Developer'

    engineerObject.setTitle('Manager');
    engineerObject.setIsManager(true);
    
    console.log(`Final Employee Profile - Title is ${engineerObject.getTitle()}. ${engineerObject.getIsManager() ? 'Is' : 'Is not'} a Manager\n`)
    // 正确操作实例属性
}

main();

验证结论:

你可以在首次console.log后添加console.log(globalThis.title)(Node.js环境)或console.log(window.title)(浏览器环境),会发现调用setTitle后这个全局变量被设置为'Manager',完全印证了之前的分析。

内容的提问来源于stack exchange,提问作者cobbdb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 15:57:39