【问题标题】:Why is it not possible to set null to an Object passed by reference in JavaScript? [duplicate]为什么不能将 null 设置为 JavaScript 中通过引用传递的对象? [复制]
【发布时间】:2020-07-30 14:37:00
【问题描述】:

我不知道为什么在下面的例子中不能给对象定义 null,但是可以给它添加属性

function callByReference(myFunc) {
  myFunc.b = 2;
  myFunc = null; // this not set null to Object arg

  // myFunc.b = 2; //If I set it after, throws error
}


let customObj = {
  a: 1
};

console.log("Before call by reference method");
console.log(customObj);

callByReference(customObj);

console.log("After call by reference method");
console.log(customObj);

即使我先将其设置为null,然后添加属性也会引发错误;

我不太了解这种行为。有什么理由吗?也许我不理解通过引用传递参数时 javascript 的工作原理

【问题讨论】:

  • 为什么你期望 null 有属性?你可能想设置 myFunc = {}
  • 因为 myFunc 是该函数的局部变量,它的 value 是引用,并且为局部变量分配新值不会影响对象引用的旧值。
  • @BhojendraRauniyar 如果我设置 myFunc = {} 该对象仍然具有属性 a
  • 您仍要删除所有属性吗?还是只是一个为什么的问题?
  • @NinaScholz 这只是一个为什么的问题,我在查看我的代码时有疑问

标签: javascript pass-by-reference


【解决方案1】:

按照 Javascript 的工作方式,每个变量名本质上都是指向某个值的指针(或引用)。当您通过引用旧对象创建新变量或调用函数时,您基本上是在复制指针。例如:

const fn = (param) => {
  // ...
};
const obj = {};
const obj2 = obj;
fn(obj);

上面,obj2param 都指向了最初在obj 中创建的空对象,你可能会认为它是:

obj: MemAddress1234
obj2: MemAddress1234
param: MemAddress1234

每当您使用= 赋值运算符时,您都会为该变量名重新分配绑定,但这样做不会影响可能指向同一事物的任何其他变量: p>

param = null;

结果类似于

obj: MemAddress1234
obj2: MemAddress1234
param: MemAddress0

至少,这是看待它的一种方式。 obj 和空对象之间的链接,以及obj2 和空对象之间的链接不受影响,因为它只是重新分配了 param 变量名。

自行重新分配变量几乎不会对其他任何东西产生任何副作用。这两个例外是 arguments 处于草率模式:

function foo(a, b) {
  console.log(arguments);
  a = 5;
  console.log(arguments);
}

foo(1, 2);

以及由 ES6 模块导出的可变变量。

【讨论】:

  • 我更喜欢术语 reference 而不是 pointer 因为规范是这样称呼它的。
  • @JonasWilms 在这里发布是否正确?我看到他们因为被复制而关闭了它。但这是另一个问题
  • @certainperformance 我明白了,马虎模式是严格模式的反面,对吧?
  • @hans 你在这里问完全没问题。不要误解“关闭”,而是我引用了一个更大的问题,具有更深入的资源,以便将来的访问者可以轻松找到它们。但这并不是真正的另一个问题,另一个问题涉及根本原因。
  • 是的,马虎模式与严格模式相反。
【解决方案2】:

首先,您创建了一个customObj 对象,该对象存储在内存中的某个位置。

那么你有一个带有参数function callByReference(myFunc)的函数。

如果您使用对象callByReference(customObj) 调用该函数,它会将指向customObj 的引用分配给myFunc。所以现在myFunc 指向内存中与customObj 相同的位置。

现在,如果您修改 内部 myFunc 的内容,您将更改与 customObj 相同的内存 - 这就是 myFunc.b = 2; 将修改 customObj 的原因。但是如果你给myFunc 分配了一些新的东西,你就是在修改它指向的地方,而不是里面的东西。所以myFunc = null; 就像告诉“现在myFunc 指向空内存”,但customObj 仍然指向内存的同一部分,所以数据是一样的。

【讨论】:

    【解决方案3】:

    这是 JavaScript 的工作方式:

    参数总是按值传递,但是当变量引用对象时,“值”就是对对象的引用。

    改变变量的值永远不会改变底层的原语或对象,它只是将变量指向一个新的原语或对象(但如果你改变一个属性,底层对象的属性也会改变)。

    【讨论】:

      猜你喜欢
      • 2015-06-18
      • 2015-08-22
      • 2013-05-22
      • 1970-01-01
      • 1970-01-01
      • 2014-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多