JavaScript的引用和值

我正在寻找一些很好的综合阅读材料,关于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?
}

如果我想要创建一个完全独立的对象副本(没有任何引用),最好的实践方法是什么?

334296 次浏览

我的理解是,这其实很简单:

  • 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总是通过值传递,但在数组或对象中,值是对它的引用,所以你可以“改变”内容。

但是,我想你们已经在SO上读过了;在这里你有你想要的文档:

< a href = " http://snook。ca /档案/ javascript / javascript_pass noreferrer“rel = > http://snook.ca/archives/javascript/javascript_pass < / >

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 = ...
  1. 基本类型变量,如string,number总是pass作为pass 李由价值。< / >
  2. 数组和对象根据这两个条件作为引用传递或值传递。

    • 如果你正在用new Object或array改变该对象或数组的值,那么它是通过value传递的。

      object1 = {item: "car"}; array1 =[1, 2, 3]; < /代码> < / p > < /李>

    这里你将新对象或数组分配给旧对象或数组。你没有改变财产的价值 旧物件。所以它是通过值传递

    • 如果你正在改变一个对象或数组的属性值,那么它是通过引用传递的。

      < p > <代码>中的object1。项=“汽车”; array1[0] = 9; < /代码> < / p > < /李>

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

代码

    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