为什么不能将 null 设置为在 JavaScript 中通过引用传递的对象?

Why is it not possible to set null to an Object passed by reference in JavaScript?

我不知道为什么在下面的示例中不能为对象定义 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 在通过引用传递参数时是如何工作的

这是 JavaScript 的工作方式:

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

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

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

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

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

obj: MemAddress1234
obj2: MemAddress1234
param: MemAddress1234

无论何时使用 = 赋值运算符,都会为该变量名称 重新分配绑定 ,但这样做不会影响可能指向的任何其他变量同样的事情:

param = null;

结果类似于

obj: MemAddress1234
obj2: MemAddress1234
param: MemAddress0

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

单独重新分配一个变量几乎不会对其他任何东西产生任何副作用。这两个例外是 arguments 在草率模式下:

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

foo(1, 2);

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

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

然后你有一个带有参数的函数 function callByReference(myFunc).

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

相同的位置

现在,如果您在 myFunc 中修改某些内容,您将更改与 customObj 相同的内存 - 这就是为什么 myFunc.b = 2; 会修改customObj。但是如果你给 myFunc 分配新的东西,你就是在修改它指向的地方,而不是里面的东西。所以myFunc = null;就像告诉"now myFunc points to null memory",但是customObj还是指向内存的同一部分,所以数据是一样的