YDKJS中Mixin复制后对象相互影响的示例疑问及代码验证
理解Mixin中的共享引用问题
嘿,我懂你的困惑!你当前的测试其实没触发《YDKJS》里提到的那种共享引用导致相互影响的场景,我来帮你理清这里的关键:
你当前测试的问题点
你修改的是Car.fooo这个函数引用本身:
Car.fooo = function () { let array = [34, 65, 1]; return array; };
这一步是给Car对象的fooo属性重新赋值了一个全新的函数,相当于把Car.fooo的引用从原本指向Vehicle.fooo的函数,改成指向你新定义的函数。这时候两个对象的fooo已经完全是独立的引用了,自然不会互相影响。
正确的共享引用影响示例
《YDKJS》说的情况,是当mixin复制的是引用类型的内部状态时(比如数组、对象),修改这个共享对象的内部内容会同时影响原对象和目标对象。来看这个例子:
function mixin(sourceObj, targetObj) { for (let key in sourceObj) { if (!(key in targetObj)) { targetObj[key] = sourceObj[key]; } } return targetObj; } const Vehicle = { engines: 1, passengers: ['Alice', 'Bob'], // 直接存储数组引用 ignition: function () { console.log('Turning on my engine'); } }; const Car = mixin(Vehicle, { wheels: 4 }); // 修改共享数组的内部元素 Car.passengers.push('Charlie'); console.log(Vehicle.passengers); // 输出: ["Alice", "Bob", "Charlie"] console.log(Car.passengers); // 输出: ["Alice", "Bob", "Charlie"]
这里Vehicle.passengers和Car.passengers指向同一个数组对象,当你修改数组的内部内容(比如push元素),两个对象都会看到变化。
如果是给Car.passengers重新赋值一个新数组:
Car.passengers = ['Dave']; console.log(Vehicle.passengers); // 还是 ["Alice", "Bob", "Charlie"]
这时候两个引用就断开了,不会互相影响——这和你之前修改fooo函数的逻辑是一样的。
适配你原有代码的示例
如果想在你原来的代码结构里看到共享影响,可以让函数返回同一个数组引用,而不是每次调用都生成新数组:
// 定义一个共享的数组 const sharedArray = [2, 2, 1]; function foo() { return sharedArray; // 每次都返回同一个数组引用 } function mixin(sourceObj, targetObj) { for (let key in sourceObj) { if (!(key in targetObj)) { targetObj[key] = sourceObj[key]; } } return targetObj; } const Vehicle = { engines: 1, fooo: foo, ignition: function () { console.log('Turning on my engine'); }, drive: function () { this.ignition(); console.log('Steering and moving forward'); } }; const Car = mixin(Vehicle, { wheels: 4, drive: function () { console.log('Rolling on all ' + this.wheels + ' wheels!'); } }); // 修改共享数组的内部 Vehicle.fooo().push(3); console.log(Vehicle.fooo()); // 输出: [2, 2, 1, 3] console.log(Car.fooo()); // 输出: [2, 2, 1, 3]
现在两个对象的fooo函数返回的是同一个数组,修改内部元素后,两边都会同步变化。
总结一下
关键区别在于:
- 如果你修改的是共享引用对象的内部状态(比如数组的元素、对象的属性),原对象和目标对象会互相影响;
- 如果你是给目标对象的属性重新赋值一个新的引用(比如新函数、新数组),两个对象的引用就断开了,不会互相影响。
内容的提问来源于stack exchange,提问作者Rustem
相关产品推荐
相关产品推荐

