为什么当我这样做时:
x = 5
(function bla(varX){
varX = 7; console.log(x); //7
})(x);
console.log(x); //5
x
不会改变,因为如果我理解正确的话,它处于闭包中,但是这里:
x = {a:5}
(function bla(varX){
varX.a = 7; console.log(varX.a);
})(x)
console.log(x.a); //7
为什么x.a
被覆盖而x
没有?
您可以对任何其他函数执行相同的操作:
var o = {};
function f(x) {
x.val = "foo";
}
f(o);
console.log(o.val);
对象浮动在堆上的某个位置,两个x
都只是对该对象的引用。你只需要一个对它的引用就可以改变一个对象,不管你是如何得到这个引用的。
另一方面,语句x = ...;
只是覆盖局部变量以引用其他内容。这也是为什么JS的没有具有传统(更有用)定义的"引用传递"。
在这两个函数中,都有一个全局x(在第一行)和一个局部x(function bla(x){
)。
在第一个示例中,您只是在更改一系列变量的值。更改局部x的值不会影响全局x。
在第二个示例中,您将对您创建的对象的引用传递给函数,而不是它的副本。在函数中,您通过为对象的一个属性分配一个新值来修改该对象。全局和局部x的值保持不变(对对象的引用)。