首页 文章

Javascript引用与 Value [重复]

提问于
浏览
329

这个问题在这里已有答案:

我正在寻找一些很好的综合阅读材料,当Javascript按值传递某些内容时,以及何时通过引用和修改传递的项目时会影响函数外部的值,何时不会 . 我还对通过引用与值分配另一个变量以及是否遵循任何不同的规则而不是作为函数参数传递感兴趣 .

我已经做了很多搜索并找到了很多具体的例子(其中很多都在SO上),我可以从中开始拼凑出真正的规则,但我还没有找到一个单一的,写得很好的文档,描述了这一切 .

此外,语言中是否有方法可以控制是通过引用还是通过值传递某些内容?

以下是我想要了解的一些问题类型 . 这些只是示例 - 我实际上是在了解语言所遵循的规则,而不仅仅是具体示例的答案 . 但是,这里有一些例子:

function f(a,b,c) {
   a = 3;
   b.push("foo");
   c.first = false;
}

var x = 4;
var y = ["eeny", "miny", "mo"];
var z = {first: true};
f(x,y,z);

对于所有不同类型,x,y和z的内容何时在f的范围之外变化?

function f() {
    var a = ["1", "2", "3"];
    var b = a[1];
    a[1] = "4";
    // what is the value of b now for all possible data types that the array in "a" might hold?
}

function f() {
    var a = [{yellow: "blue"}, {red: "cyan"}, {green: "magenta"}];
    var b = a[1];
    a[1].red = "tan";
    // what is the value of b now and why?
    b.red = "black";
    // did the value of a[1].red change when I assigned to b.red?
}

如果我想制作一个完全独立的对象副本(没有任何参考),那么最佳实践方法是什么?

4 回答

  • 567

    Javascript总是按值传递 . 但是,如果将对象传递给函数,"value"实际上是对该对象的引用,因此该函数可以修改该对象的属性,但不会导致函数外部的变量指向其他对象 .

    一个例子:

    function changeParam(x, y, z) {
      x = 3;
      y = "new string";
      z["key2"] = "new";
      z["key3"] = "newer";
    
      z = {"new" : "object"};
    }
    
    var a = 1,
        b = "something",
        c = {"key1" : "whatever", "key2" : "original value"};
    
    changeParam(a, b, c);
    
    // at this point a is still 1
    // b is still "something"
    // c still points to the same object but its properties have been updated
    // so it is now {"key1" : "whatever", "key2" : "new", "key3" : "newer"}
    // c definitely doesn't point to the new object created as the last line
    // of the function with z = ...
    
  • 25

    是的,Javascript总是按值传递,但在数组或对象中,值是对它的引用,因此您可以“更改”内容 .

    但是,我认为你已经在SO上阅读了它; here你有你想要的文件:

    http://snook.ca/archives/javascript/javascript_pass

  • 13

    我的理解是,这实际上非常简单:

    • Javascript始终按值传递,但是当变量引用对象(包括数组)时,"value"是对象的引用 .

    • 更改变量的值永远不会更改基础图元或对象,它只是将变量指向新的图元或对象 .

    • 但是,更改变量引用的对象的属性会更改基础对象 .

    因此,要完成一些示例:

    function f(a,b,c) {
        // Argument a is re-assigned to a new value.
        // The object or primitive referenced by the original a is unchanged.
        a = 3;
        // Calling b.push changes its properties - it adds
        // a new property b[b.length] with the value "foo".
        // So the object referenced by b has been changed.
        b.push("foo");
        // The "first" property of argument c has been changed.
        // So the object referenced by c has been changed (unless c is a primitive)
        c.first = false;
    }
    
    var x = 4;
    var y = ["eeny", "miny", "mo"];
    var z = {first: true};
    f(x,y,z);
    console.log(x, y, z.first); // 4, ["eeny", "miny", "mo", "foo"], false
    

    例2:

    var a = ["1", "2", {foo:"bar"}];
    var b = a[1]; // b is now "2";
    var c = a[2]; // c now references {foo:"bar"}
    a[1] = "4";   // a is now ["1", "4", {foo:"bar"}]; b still has the value
                  // it had at the time of assignment
    a[2] = "5";   // a is now ["1", "4", "5"]; c still has the value
                  // it had at the time of assignment, i.e. a reference to
                  // the object {foo:"bar"}
    console.log(b, c.foo); // "2" "bar"
    
  • 52
    • 像字符串一样的原始类型变量,数字总是按值传递 .

    • Array和Object作为传递引用传递或基于这两个条件传递值 .

    • 如果要使用新的Object或Array更改该Object或数组的值,则它将通过Value传递 .

    object1 = {item: "car"}; array1=[1,2,3];

    在这里,您将新对象或数组分配给旧对象 . 您不会更改旧对象的属性值 . 因此它是按值传递的 .

    • 如果要更改对象或数组的属性值,则它将通过Reference传递 .

    object1.item= "car"; array1[0]=9;

    这里你要更改旧对象的属性值 . 你没有将新对象或数组分配给旧对象 . 所以它是通过引用传递的 .

    Code

    function passVar(object1, object2, number1) {
    
            object1.key1= "laptop";
            object2 = {
                key2: "computer"
            };
            number1 = number1 + 1;
        }
    
        var object1 = {
            key1: "car"
        };
        var object2 = {
            key2: "bike"
        };
        var number1 = 10;
    
        passVar(object1, object2, number1);
        console.log(object1.key1);
        console.log(object2.key2);
        console.log(number1);
    
    Output: -
        laptop
        bike
        10
    

相关问题