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

对象内部别名指向异常:创建正常后续指向最后对象的原因与解决

问题分析与解决

问题代码

function obj() {};
obj.prototype.custom = function () { 
    this.custom.alias = this;
    this.check();
}
obj.prototype.check = function () { 
    console.log(this === this.custom.alias);
}
os = []; 
for (let i = 1; i <= 10; i++) { 
    let o = new obj(); 
    o.custom(); 
    os.push(o);
}
for (let o of os) {
    o.check();
}

问题现象

创建10个对象时,每次调用custom()都会输出true;但循环结束后遍历所有对象调用check(),前9个都会输出false,只有最后一个是true。

问题原因

核心问题出在**this.custom指向的是原型链上的共享函数**:

  • obj.prototype.custom是定义在原型上的方法,所有obj实例都会共享同一个custom函数对象。
  • 当你执行this.custom.alias = this时,并不是给当前实例添加属性,而是给原型上的那个custom函数添加alias属性。
  • 每次创建新实例调用custom(),都会覆盖custom函数的alias属性,最后这个alias会指向最后一个创建的实例。
  • 所以后续所有实例调用check()时,this.custom.alias取的都是原型上custom函数的alias,自然只有最后一个实例能匹配上。

解决方法

要让每个实例的别名只指向自己,需要给每个实例单独存储别名,而不是复用原型上的函数属性,有两种常用方式:

方法1:给实例添加独立属性存储别名

修改custom和check方法,把别名存在实例自身的属性里:

function obj() {};
obj.prototype.custom = function () { 
    // 给当前实例添加_alias属性,指向自身
    this._alias = this;
    this.check();
}
obj.prototype.check = function () { 
    console.log(this === this._alias);
}
os = []; 
for (let i = 1; i <= 10; i++) { 
    let o = new obj(); 
    o.custom(); 
    os.push(o);
}
for (let o of os) {
    o.check();
}

这样每个实例的_alias都是自己的属性,互相独立,不会被覆盖。

方法2:给每个实例分配独立的custom方法

如果一定要保留custom.alias的形式,可以在构造函数里给每个实例创建专属的custom函数,这样每个实例的custom都是独立的,它的alias也不会互相影响:

function obj() {
    // 每个实例都有自己的custom函数
    this.custom = () => {
        this.custom.alias = this;
        this.check();
    }
};
obj.prototype.check = function () { 
    console.log(this === this.custom.alias);
}
os = []; 
for (let i = 1; i <= 10; i++) { 
    let o = new obj(); 
    o.custom(); 
    os.push(o);
}
for (let o of os) {
    o.check();
}

这种方式虽然能实现需求,但每个实例都创建新函数,会增加内存开销,一般推荐第一种方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 02:22:27