Javascript函数是否默认通过引用或值返回对象

Does a Javascript function return objects by reference or value by default?

本文关键字:返回 对象 引用 函数 是否 默认 Javascript      更新时间:2023-09-26

我在函数外部的全局范围中定义了一个对象。此对象不会作为参数传递到函数中,但函数会对其进行修改并返回修改后的对象。

我想知道的是,函数是返回对象的副本,还是返回原始全局对象?

此外,由于对象是通过引用传递到函数中的,因此将该对象作为参数传递到函数会有什么不同吗?

无论何时返回对象,都会返回对该对象的引用。同样,当你传递一个对象时,你也传递了一个引用。但是,如以下示例所示,将对象作为参数传入可能与仅在全局范围内更改对象不同。这是因为对对象的引用本身是通过值传递的。

如果要更改对象的成员,那么将其作为参数传入还是仅更新全局对象都没有区别。无论哪种方式,您都在使用同一个对象。

示例1:

var object = {foo:'original'};
function changeObject() {
    object.foo = 'changed';
    return object;
}
console.log(changeObject()); // outputs {foo:'changed'}
console.log(object); // outputs {foo:'changed'}

示例2:

var object = {foo:'original'};
function changeArgument(object) {
    object.foo = 'changed';
    return object;
}
console.log(changeArgument(object));  // outputs {foo:'changed'}
console.log(object);  // outputs {foo:'changed'}

另一方面,如果用新对象覆盖对象,则如果对参数进行更改,更改将不会持续,但如果对全局对象进行更改,则更改将持续。这是因为参数通过值传递对对象的引用。一旦将该值替换为对新对象的引用,就不再是在谈论同一个对象。

示例3:

var object = {foo:'original'};
function replaceObject() {
    object = {foo:'changed'};
    return object;
}
console.log(replaceObject()); // outputs {foo:'changed'}
console.log(object); // outputs {foo:'changed'}

示例4:

var object = {foo:'original'};
function replaceArgument(object) {
    object = {foo:'changed'};
    return object;
}
console.log(replaceArgument(object)); // outputs {foo:'changed'}
console.log(object); // outputs {foo:'original'}

可能是后期评论,但这在任何语言中都是典型的挑战。在堆上创建并通过引用传递的对象,而不是基元(按值)。我认为问题的根源是共享实例与唯一实例,以避免不受欢迎的影响。例如,我们调用一个函数来获取一个模板(对象),供新用户添加到集合中或希望清除表单在取消事件上从不同模块重新启动。它很容易理解,也很容易被忽视。。测试用例通常不包括所有使用排列

健全性检查表:

这里的共享实例:

var bigo = {
    usr: { name: 'steven' },
    bigi: function () {
        return this.usr;
    }
};   
var outA = bigo.bigi();
var outB = bigo.bigi();
print(outA.name); // => steven
print(outB.name); // => steven
outA.name = 'ilan'; // change value
print(outA.name); // => ilan
print(outB.name); // => ilan

非共享实例:

var bigo = {
    bigi: function () {
        var user = { name: 'steven' };
        return user;
    }
};   
var outA = bigo.bigi();
var outB = bigo.bigi();
print(outA.name); // => steven
print(outB.name); // => steven
outA.name = 'ilan'; // change value
print(outA.name); // => ilan
print(outB.name); // => steven

我想知道的是,函数是返回对象的副本,还是返回原始全局对象?

实际上,您只能在JavaScript中处理对对象的引用。即使是var foo = {}也只是将对新对象的引用分配给foo

如果对象在函数外,则不需要"返回"它。如果在函数内修改对象,它将更新对象本身。然后,您可以根据需要在其他函数中引用新更新的对象。

根据您的问题,我认为您的代码(或多或少)是这样的:

var o = {};
function f() {
    o.prop = true;
    return o;
}
  1. 在这种情况下,全局变量o引用一个对象
  2. 当您修改o时,您将修改o引用的任何内容。因此,它会修改原始对象
  3. 当您返回o时,您将返回对原始对象的引用

将对象传递给函数会导致传递对原始对象的引用。因此,任何修改都会影响原始对象。例如:

var o = {};
f(o);
console.log(o.prop); // true
function f(o) {
    o.prop = true;
}