JavaScript 按引用与按值 [英] JavaScript by reference vs. by value
问题描述
我正在寻找一些很好的综合阅读材料,了解 JavaScript 何时按值传递某项内容,何时按引用传递,以及何时修改传递的项会影响函数外的值,何时不影响该值.我还感兴趣的是,当分配给另一个变量时是按引用还是按值,以及这是否遵循与作为函数参数传递不同的规则.
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.
我已经做了很多搜索并找到了很多具体的例子(其中很多都在 SO 上),从中我可以开始拼凑出真正的规则,但我还没有找到一个,好吧描述这一切的书面文件.
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.
另外,语言中有没有办法控制某些东西是按引用传递还是按值传递?
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);
对于所有不同类型,x、y 和 z 的内容何时在 f 的范围之外发生变化?
When are the contents of x, y and z changed outside the scope of f for all the different types?
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?
推荐答案
我的理解其实很简单:
- Javascript总是按值传递,但是当变量引用一个对象(包括数组)时,值"就是对对象的引用.
- 改变一个变量的值永远不会改变底层的原语或对象,它只是将变量指向一个新的原语或对象.
- 但是,更改变量引用的对象的属性确实会更改底层对象.
- Javascript is always pass 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 never changes the underlying primitive or object, it just points the variable to a new primitive or object.
- However, changing a property of an object referenced by a variable does change the underlying object.
所以,通过你的一些例子:
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
示例 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 按引用与按值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!