作为参数传递到函数中的对象的引用是否会更改

Will the reference of an object passed into a function as a parameter change?

本文关键字:是否 引用 对象 参数传递 函数      更新时间:2023-09-26

为什么在函数中更改a引用后未定义a.y

var a = { x : 1 };
a = { y : 2 };
function _change(b) {
    b = { y : 3 };
    return b;
}
_change(a);
document.write(a.y);   // undefined
document.write(a.x);   //1

下面的代码行为不同

var a = {x:1};
var b={y:1};
b=a;
a.x //undefined
a.y //1

为什么?

因为您完全更改了带有{y:2}的对象{x:1},因此对象中没有 x 属性。

我认为您需要像这样使用:

var a = {x:1};
a.y = 2;//assign y = 2 in a oject.

因此,在更改函数中执行相同的操作。


第一个区块

这是我通过逐行运行代码得到的:

var a = {x:1};  // <-- sets a to the object {x:1}
a = {y:2}; // <-- sets a to the object {y:2}, so it no longer has a.x = 1
function _change(b)
{
    b= { y:3};
    return b;
}
_change(a); // <-- this doesn't change a, it returns {y: 3} but it is not used
document.write(a.y); // 2 actually
document.write(a.x); // undefined


让我们试着理解它...

var a = {x:1};

在那里你声明变量a,你创建一个对象{x:1},并将a设置为该对象。

a = {y:2};

在那里,您可以创建一个新对象{y:2}并为其设置a。所以a不再有第一个对象。

所以......当你要求a.y它有2,当你要求a.xundefined,因为对象{y:2}没有x。请记住,您将变量a的对象从{x:1}替换为{y:2}


相反,您可以动态添加字段,如下所示:

var a = {x:1};  // <-- sets a to the object {x:1}
a.y = 2; // <-- Add a field y to the object of the variable a, it has the value 2
function _change(b)
{
    b.y = 3; // <-- actually modify the object, now the field y has value 3
    return b;
}
_change(a);
document.write(a.y); // 3
document.write(a.x); // 1


第二块

再说一次,我得到的结果和你不一样...我想知道你在哪里运行你的代码。

var a = {x:1}; // <-- sets a to the object {x:1}
var b={y:1}; // <-- sets b to the object {y:1}
b=a; // <-- now sets b to the object {x:1} - nobody has {y:1} anymore
document.write(a.x); // 1 actually
document.write(a.y); // undefined

好的,所以当你说b=a时,你正在使变量b指向与变量相同的对象 a .通过这样做,变量b不再指向对象{x:1}...这无关紧要,因为您无论如何都没有使用变量b

变量a一直{x:1},您可以看到它没有任何y定义字段。


似乎是您认为分配对象会以某种方式融合对象,导致双方都有字段的组合......如果您打算这样做,您可能会对如何动态合并两个 JavaScript 对象的属性感兴趣?。

您需要对此进行分解并理解不同词汇范围内的变量。

a全局词汇范围:

var a = {x:1};
a = {y:2};

上述初始化将解析为:

a = {y:2};
//hence at this global lexical scope 
//`lexicalscope = {"a":{y:2}};`

现在,让我们看看函数词法范围内的变量:

function _change(b){
       // at the function's `lexicalEnvironment = {"b":{y:2}}`
        b= { y:3};
       //  at this point `lexicalEnvironment = {"b":{y:3}}`
        return b;  //returned {y:3}.
    }

当以 a 作为其参数调用函数时。

_change(a); // obtained {y:3} but not captured.

我很想在这里包含关于为什么a的值不会在此答案的函数范围之外发生变化的美丽解释,但是,不想重复原始答案。不过想分享相关部分,

实际上,这意味着如果您更改参数本身(如 a), 这不会影响喂食的物品 到参数中。但是如果你改变参数的内部,比如 b.y = 3, 这将重新传播。

同样,在全局词法范围内打印它们的值。

console.log(a.y); // still in the global lexical environment a.y = 2;
console.log(a.x); // `a.x` is undefined in the global Lexical Environment.