JavaScript 按引用与按值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6605640/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaScript by reference vs. by value
提问by jfriend00
I'm looking for some good comprehensive reading material on when JavaScript passes something by value and when by reference and when modifying a passed item affects the value outside a function and when not. I'm also interested in when assigning to another variable is by reference vs. by value and whether that follows any different rules than passing as a function parameter.
我正在寻找一些很好的综合阅读材料,了解 JavaScript 何时按值传递某些内容,何时按引用传递,以及何时修改传递的项目会影响函数外的值,何时不会。我也对分配给另一个变量时是按引用还是按值感兴趣,以及是否遵循与作为函数参数传递不同的规则。
I've done a lot of searching and find lots of specific examples (many of them here on SO) from which I can start to piece together pieces of the real rules, but I haven't yet found a single, well written document that describes it all.
我已经做了很多搜索并找到了很多具体的例子(其中很多都在 SO 上),从中我可以开始拼凑出真正的规则,但我还没有找到一个单独的、写得很好的文档描述了这一切。
Also, are there ways in the language to control whether something is passed by reference or by value?
此外,语言中是否有方法控制某些内容是通过引用还是通过值传递?
Here are some of the types of questions I want to understand. These are just examples - I'm actually looking to understand the rules the language goes by, not just the answers to specific examples. But, here are some examples:
以下是我想了解的一些问题类型。这些只是示例 - 我实际上希望了解语言所遵循的规则,而不仅仅是特定示例的答案。但是,这里有一些例子:
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);
When are the contents of x, y and z changed outside the scope of f for all the different types?
对于所有不同类型,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?
}
If I want to make a fully independent copy of an object (no references whatsoever), what's the best practice way to do that?
如果我想制作一个完全独立的对象副本(没有任何引用),那么最好的做法是什么?
回答by nrabinowitz
My understanding is that this is actually very simple:
我的理解是,这实际上很简单:
- Javascript is alwayspass by value, but when a variable refers to an object (including arrays), the "value" is a reference to the object.
- Changing the value of a variable neverchanges the underlying primitive or object, it just points the variable to a new primitive or object.
- However, changing a propertyof an object referenced by a variable does change the underlying object.
- Javascript总是按值传递,但是当变量引用对象(包括数组)时,“值”就是对对象的引用。
- 改变一个变量的值永远不会改变底层的原语或对象,它只是将变量指向一个新的原语或对象。
- 但是,更改变量引用的对象的属性确实会更改底层对象。
So, to work through some of your examples:
因此,要完成您的一些示例:
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
Example 2:
示例 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"
回答by nnnnnn
Javascript alwayspasses by value. However, if you pass an object to a function, the "value" is really a reference to that object, so the function can modify that object's properties but not cause the variable outside the function to point to some other object.
Javascript总是按值传递。但是,如果将对象传递给函数,则“值”实际上是对该对象的引用,因此该函数可以修改该对象的属性,但不会导致函数外部的变量指向某个其他对象。
An example:
一个例子:
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 = ...
回答by Edgar Villegas Alvarado
Yes, Javascript always passes by value, but in an array or object, the value is a reference to it, so you can 'change' the contents.
是的,Javascript 总是按值传递,但在数组或对象中,值是对它的引用,因此您可以“更改”内容。
But, I think you already read it on SO; hereyou have the documentation you want:
但是,我认为您已经在 SO 上阅读了它;在这里你有你想要的文件:
回答by Mukund Kumar
- Primitive type variable like string,number are always pass as pass by value.
Array and Object is passed as pass by reference or pass by value based on these two condition.
if you are changing value of that Object or array with new Object or Array then it is pass by Value.
object1 = {item: "car"}; array1=[1,2,3];
here you are assigning new object or array to old one.you are not changing the value of property of old object.so it is pass by value.
if you are changing a property value of an object or array then it is pass by Reference.
object1.item= "car"; array1[0]=9;
here you are changing a property value of old object.you are not assigning new object or array to old one.so it is pass by reference.
- 像字符串、数字这样的原始类型变量总是按值传递。
数组和对象根据这两个条件作为按引用传递或按值传递。
如果您正在使用新对象或数组更改该对象或数组的值,则它是按值传递的。
object1 = {item: "car"}; array1=[1,2,3];
在这里,您将新对象或数组分配给旧对象。您没有更改旧对象的属性值。因此它是按值传递的。
如果您正在更改对象或数组的属性值,则它是通过引用传递的。
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