使用Object.create()创建对象时数组属性的引用异常问题问询
为什么用Object.create()创建的新对象修改数组属性会影响原型对象?
这其实是JavaScript原型链和引用类型/基本类型差异共同作用的结果,我来给你拆解清楚:
首先得明白Object.create(obj)到底做了什么:它会创建一个全新的对象obj2,并且把obj2的原型(也就是__proto__)指向你传入的obj。这意味着,当你访问obj2的某个属性时,如果obj2自身没有这个属性,JavaScript就会顺着原型链往上找,直到找到这个属性或者到达原型链顶端。
接下来看你的代码里的不同属性类型:
1. 数组(引用类型)的情况
你的obj里的color是一个数组,属于引用类型。当你执行obj2.color.push('blue')时:
- 首先检查
obj2自身有没有color属性?没有,所以去原型链找,找到了obj的color数组。 push操作不是给obj2赋值新的数组,而是直接修改了这个数组本身——因为你拿到的是原型上数组的引用,操作这个引用指向的对象,自然会影响原型里的原数组。
2. 基本类型(比如字符串)的情况
再看cat属性,它是字符串(基本类型):
- 当你执行
obj2.cat = 'Fluffy'时,JavaScript会直接在obj2自身添加一个cat属性,而不是去修改原型上的cat。 - 之后你访问
obj2.cat时,会优先用自身的属性,原型上的cat('Kitty')完全不受影响。
3. 对象类型的两种操作
你的state属性也是引用类型,这里你做的是obj2.state = {complete: false}——这其实是给obj2自身赋值了一个新对象,相当于断开了和原型state的引用,所以修改这个新对象不会影响原型的state。但如果是这样写:
obj2.state.complete = false;
那结果就和数组一样了:因为obj2自身没有state,会找到原型的state对象,修改它的complete属性,原型的state也会跟着变。
怎么避免这种情况?
如果想让新对象的引用类型属性不依赖原型的引用,你需要在新对象上创建自己的属性副本:
// 复制数组 obj2.color = [...obj.color]; // 或者复制对象 obj2.state = {...obj.state};
这样obj2就有了自己的数组/对象,修改它们就不会影响原型了。
内容的提问来源于stack exchange,提问作者nepdev
相关产品推荐
相关产品推荐

