展开运算符{...obj}仅复制对象自身可枚举属性,不保留原型链、不可枚举属性及symbol属性,导致instanceof失效和方法丢失;需保留原型时应使用object.create()+object.assign()或构造函数重建。

展开运算符不保留原型链
用 {...obj} 展开对象时,只会复制对象自身的可枚举属性,不会继承或保留原型上的方法和属性。比如一个通过 class 实例化出来的对象,展开后得到的是纯普通对象,instanceof 判断会失败,也无法访问原型链上的方法。
常见问题表现
例如:
用于 inference.sh 的 JavaScript/TypeScript SDK,可运行 AI 应用、构建代理、集成 150+ 模型。包名:@inferencesh/sdk(npm install),完整 TypeScript 支持。
class User {
constructor(name) {
this.name = name;
}
greet() { return `Hello, ${this.name}`; }
}
const u = new User('Alice');
const copy = { ...u }; // { name: 'Alice' }
console.log(copy.greet()); // TypeError: copy.greet is not a function
console.log(copy instanceof User); // false
需要保留原型时的替代方案
若必须维持原型关系,不能依赖展开运算符,可考虑:
- Object.create() + Object.assign():显式指定原型并拷贝自有属性
- Object.assign(Object.create(Object.getPrototypeOf(obj)), obj)
- 对 class 实例,更稳妥的是调用其构造函数重新创建,或使用深克隆库(如 lodash 的
cloneDeepWith自定义处理) - 避免在需要原型行为的场景中直接展开实例对象
不可枚举属性与 Symbol 属性也丢失
展开运算符只处理可枚举的自有属性。通过 Object.defineProperty 设置的 enumerable: false 属性、Symbol 键(除非显式列出)、以及原型链上的任何内容,均不会出现在展开结果中。










