提问人:jfriend00 提问时间:7/7/2011 最后编辑:Ry-jfriend00 更新时间:12/12/2019 访问量:343291
JavaScript by reference vs. by value [duplicate] (按引用 JavaScript 与按值 [duplicate]
JavaScript by reference vs. by value [duplicate]
问:
我正在寻找一些好的综合阅读材料,了解 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"
评论
Changing the value of a variable never changes the underlying primitive or object. However, changing a property of an object referenced by a variable does change the underlying object.
这两句话放在一起,消除了很多疑虑。谢谢!
var users = [1,2,3,4]; var x_users = users; x_users.push(5);
现在用户和x_users是相同的,因为它是通过引用传递的。解决此问题的一种方法是现在用户和x_users不同,因为x_users不是指用户。我花了一段时间才弄清楚:-)希望这可以帮助某人。var x_users = users.slice(0); x_users.push(6);
是的,Javascript 总是按值传递,但在数组或对象中,值是对它的引用,因此您可以“更改”内容。
但是,我想你已经在 SO 上读过它了;在这里,你有你想要的文档:
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 = ...
评论
Array
是一个对象,所以也会改变。
- 原始类型变量,如 string、number 始终作为 pass 传递 按值。
数组和对象基于这两个条件作为传递引用或传递值传递。
如果要使用新的 Object 或 Array 更改该 Object 或数组的值,则它是按 Value 传递的。
object1 = {item: "car"}; array1=[1,2,3];
在这里,您将新对象或数组分配给旧对象或数组。您没有更改 Property 的值 的旧 object.so 它是按值传递的。
如果要更改对象或数组的属性值,则该值将按引用传递。
object1.item= "car"; array1[0]=9;
在这里,您正在更改旧对象的属性值。您不会将新对象或数组分配给旧对象或数组,one.so 它是通过引用传递的。
法典
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
评论