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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:46:34