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

React/TypeScript扩展运算符复制类实例引发compareTo方法异常原因

扩展运算符复制类实例后箭头方法this绑定异常的原因分析

先看你的代码:

定义的Item类:

class Item {
    id:number;
    constructor(id:number) {
        this.id = id;
    }
    compareTo = (i2:Item) => {
        return this.id === i2.id;
    }
}

复制实例后的测试代码:

const selectedObj = { item: new Item(1) };
let item:Item = {...selectedObj.item};
console.log(item.id) // 1
console.log(item.compareTo(item)) //true
item.id = 123;
console.log(item.id) //123
console.log(item.compareTo(item)) //false

问题根源

核心原因是箭头函数作为类属性时,this在定义阶段就绑定到了原实例,和复制后的新对象无关:

  • 用{...selectedObj.item}做浅拷贝时,只是把原实例的可枚举属性(包括id和compareTo箭头函数)复制到了一个新的普通对象上(这个新对象并不是Item类的实例,只是结构类似的对象)。
  • compareTo作为箭头函数,它的this在原实例new Item(1)创建时就已经固定指向原实例,所以不管你怎么修改新对象的id,调用compareTo时,函数内部的this.id始终是原实例的id=1。
  • 修改新对象的id为123后,调用compareTo(item)时,this.id是原实例的1,i2.id是新对象的123,自然返回false。

解决方法

把compareTo改成类的原型方法,不要用箭头函数定义:

class Item {
    id: number;
    constructor(id: number) {
        this.id = id;
    }
    // 普通原型方法,this在调用时绑定到当前对象
    compareTo(i2: Item) {
        return this.id === i2.id;
    }
}

这样修改后,compareTo挂载在Item.prototype上,调用item.compareTo(item)时,this会自动绑定到调用方法的对象(复制后的新对象),此时this.id就是新对象的当前值,对比结果符合预期。

另外要注意:扩展运算符{...}复制类实例时不会拷贝原型上的方法,如果你需要新对象保留Item类的所有原型方法,更规范的做法是创建类的新实例,比如:

let item: Item = new Item(selectedObj.item.id);

或者在类里添加一个拷贝方法:

class Item {
    id: number;
    constructor(id: number) {
        this.id = id;
    }
    compareTo(i2: Item) {
        return this.id === i2.id;
    }
    copy(): Item {
        return new Item(this.id);
    }
}

// 使用拷贝方法
let item: Item = selectedObj.item.copy();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 01:43:20