node.js Javascript 函数是否默认按引用或值返回对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15006287/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 13:39:41  来源:igfitidea点击:

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

javascriptnode.js

提问by Hammad Akhwand

I have an object defined outside the function, in a global scope. This object is not passed into the function as an argument, but the function does modify it and return the modified object.

我在函数外部定义了一个对象,在全局范围内。这个对象不会作为参数传递给函数,但函数会修改它并返回修改后的对象。

What I wanted to know is, if the function returns a copy of the object, or the original global object?

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

Also, will passing that object to the function as an argument, make a difference, since objects are passed into functions by reference?

另外,由于对象是通过引用传递给函数的,所以将该对象作为参数传递给函数会产生影响吗?

回答by Tim Goodman

Whenever you're returning an object, you're returning a reference to the object. Likewise, when you're passing an object, you're passing a reference. However, passing an object in as an argument canbe different than just changing an object in global scope, as these examples show. This is because the reference to the object is itself passed by value.

每当您返回一个对象时,您就是在返回对该对象的引用。同样,当你传递一个对象时,你传递了一个引用。然而,在传递一个对象作为参数不仅仅是改变全球范围内的对象,因为这些例子表明不同。这是因为对对象的引用本身是按值传递的。

If you're changing the members of an object, then whether you pass it in as an argument or just update the global object makes no difference. Either way, you're working with the same object.

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

Example 1:

示例 1:

var object = {foo:'original'};

function changeObject() {
    object.foo = 'changed';
    return object;
}

console.log(changeObject()); // outputs {foo:'changed'}
console.log(object); // outputs {foo:'changed'}

Example 2:

示例 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'}

On the other hand, if you're overwriting the object with a new object, the change won't persist if you do it to the argument, but will persist if you do it to the global object. That's because the argument passes the reference to the object by value. Once you replace this value with a reference to a new object, you're not talking about the same object anymore.

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

Example 3:

示例 3:

var object = {foo:'original'};

function replaceObject() {
    object = {foo:'changed'};
    return object;
}

console.log(replaceObject()); // outputs {foo:'changed'}
console.log(object); // outputs {foo:'changed'}

Example 4:

示例 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'}

回答by algor

May be late comment, but this is typical challenge in any language. Objects created on the heap and passed around by reference opposed to primitives(by value). I think the root of the question is shared instance versus unique one to avoid unwelcome effects. For example we calling a function to get a template(object) for new user to add to collection or want to clear the form on cancel event from different modules to start over. It easy to understand and easy to overlook..test cases typically not covering all usage permutations

可能是迟到的评论,但这是任何语言的典型挑战。在堆上创建并通过引用传递的对象与基元(按值)相反。我认为问题的根源是共享实例与唯一实例以避免不受欢迎的影响。例如,我们调用一个函数来获取新用户的模板(对象)以添加到集合中,或者想要清除来自不同模块的取消事件表单以重新开始。很容易理解也很容易忽略……测试用例通常不涵盖所有的使用排列

The sanity checklist:

健全性检查表:

Here the shared instance:

这里是共享实例:

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

Non shared instance:

非共享实例:

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

回答by Quentin

What I wanted to know is, if the function returns a copy of the object, or the original global object?

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

Effectively, you only ever deal with references to objects in JavaScript. Even var foo = {}just assigns a reference to a new object to foo.

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

回答by LoneWolfPR

If the object is outside the function, you don't need to 'return' it. If you modify the object within the function it will update the object itself. Then you can reference the newly updated object in other functions as needed.

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

回答by Aadit M Shah

From your question this is how I think your code looks (more or less):

从您的问题来看,这就是我认为您的代码的外观(或多或少):

var o = {};

function f() {
    o.prop = true;
    return o;
}
  1. In this case the global variable oreferences an object.
  2. When you modify oyou're modify whatever oreferences. Hence it modifies the original object.
  3. When you return oyou're returning a reference to the original object.
  1. 在这种情况下,全局变量o引用一个对象。
  2. 当您修改时,o您正在修改任何o引用。因此它修改了原始对象。
  3. 当您返回时,o您将返回对原始对象的引用。

Passing the object to a function results in the reference to the original object being passed. Hence any modifications will affect the original object. For example:

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

var o = {};

f(o);

console.log(o.prop); // true

function f(o) {
    o.prop = true;
}