Javascript函数默认是通过引用还是值返回对象?

Ham*_*and 19 javascript node.js

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

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

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

Tim*_*man 45

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

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

例1:

var object = {foo:'original'};

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

console.log(changeObject()); // outputs {foo:'changed'}
console.log(object); // outputs {foo:'changed'}
Run Code Online (Sandbox Code Playgroud)

例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'}
Run Code Online (Sandbox Code Playgroud)

另一方面,如果您使用新对象覆盖对象,则在对参数执行此操作时更改将不会保留,但如果对全局对象执行此操作,则更改将保持不变.那是因为参数通过值传递对象的引用.将此值替换为对新对象的引用后,您不再讨论同一个对象了.

例3:

var object = {foo:'original'};

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

console.log(replaceObject()); // outputs {foo:'changed'}
console.log(object); // outputs {foo:'changed'}
Run Code Online (Sandbox Code Playgroud)

例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'}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的答案. (6认同)

小智 5

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

理智检查表:

这里是共享实例:

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
Run Code Online (Sandbox Code Playgroud)

非共享实例:

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
Run Code Online (Sandbox Code Playgroud)