Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/411.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript函数是否默认通过引用或值返回对象?_Javascript_Node.js - Fatal编程技术网

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

Javascript函数是否默认通过引用或值返回对象?,javascript,node.js,Javascript,Node.js,我在函数外部定义了一个对象,在全局范围内。此对象不会作为参数传递到函数中,但函数会修改它并返回修改后的对象 我想知道的是,如果函数返回对象的副本,还是原始全局对象 此外,将该对象作为参数传递给函数是否会产生影响,因为对象是通过引用传递给函数的 我想知道的是,如果函数返回对象的副本,还是原始全局对象 实际上,您只处理JavaScript中对象的引用。即使是var foo={}也只是将一个对新对象的引用分配给foo如果对象在函数之外,则不需要“返回”它。如果在函数中修改对象,它将更新对象本身。然后,

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

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

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

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


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

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

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

  • 在这种情况下,全局变量
    o
    引用一个对象
  • 当您修改
    o
    时,您正在修改任何
    o
    引用。因此,它会修改原始对象
  • 当您返回
    o
    时,您将返回对原始对象的引用
  • 将对象传递给函数会导致传递对原始对象的引用。因此,任何修改都将影响原始对象。例如:

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

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

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

    例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
    
    非共享实例:

    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
    

    对象永远不会被复制,除非你明确地这样做。与其说“对象是通过引用传递到函数中的”,不如说对对象的引用是通过值传递的。看这里:这是有道理的。然而,在我的例子中,返回它有助于将单个对象从一个巨大的集合中分离出来,这样我就不需要再次查找该对象了。我不太明白你当时的处境。您可以发布一个代码示例吗?当然,如果您希望
    replaceArgument(object)
    具有与
    replaceObject
    相同的最终结果,您可以只做
    object=replaceArgument(object)
    这是一个很好的答案,并为我澄清了一些问题。