JavaScript按引用还是按值[重复]

2020/09/29 08:21 · javascript ·  · 0评论

我正在寻找一些关于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?
}

如果我想制作一个对象的完全独立副本(什么都没有引用),那么这样做的最佳实践方法是什么?

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

  • Javascript 总是按值传递,但是当变量引用对象(包括数组)时,“值”是对对象的引用。
  • 更改变量的值永远不会更改基础原语或对象,而只是将变量指向新的原语或对象。
  • 但是,更改变量引用的对象属性确实会更改基础对象。

因此,通过一些示例:

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"

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

一个例子:

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 = ...

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

但是,我想您已经在SO上阅读了;在这里,您拥有所需的文档:

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

  1. 原始类型变量(例如字符串,数字)始终作为按值传递。
  2. 根据这两个条件,数组和对象按引用传递或按值传递。

    • 如果要使用新的对象或数组更改该对象或数组的值,则按值传递。

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

    在这里,您将新对象或数组分配给旧对象或数组。您没有更改旧对象的属性值,因此按值传递。

    • 如果要更改对象或数组的属性值,则通过引用传递它。

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

    在这里,您正在更改旧对象的属性值。您没有将新对象或数组分配给旧对象。因此它通过引用传递。

    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
本文地址:http://javascript.askforanswer.com/javascriptanyinyonghuanshianzhizhongfu.html
文章标签: ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!