Why do objects changed in function change what they point to in memory, but sometimes create a new memory object?
我在这篇博客上读到了如果一个对象或数组在函数内部发生了变化,那么指向内存中的值也会发生变化,就像它在函数外部发生了变化一样。
1 2 3 4 5 | var a = [1,2,3], b = a; b[0] = 5; console.log(a); // [5, 2, 3] |
结果与
1 2 3 4 5 6 7 8 9 10 | var a = [1,2,3], b = a; var arrayFunction = function(arr){ arr[0] = 10; }; var arr = arrayFunction(b); console.log(a, b, arr) // [10, 2, 3], [10, 2, 3], [10, 2, 3]; |
然而,我无法理解的是,为什么在函数内重新分配多个数组值不会改变函数外部的值:
1 2 3 4 5 6 7 8 9 10 11 | var a = [1,2,3], b = a; var arrayFunction = function(arr){ arr = ["a","b","c"]; return arr; }; var result = arrayFunction(b); console.log(result) //["a","b","c"] console.log(a, b); //[1, 2, 3], [1, 2, 3] |
为什么这不会像第一个例子那样改变内存中的指向值?
在JSbin上编写示例可能更好
这是因为JavaScript中的对象实际上不是通过引用传递的。我见过它被称为"通过复制引用传递",或者"通过句柄传递"——这两种方法都能更好地描述实际发生的事情。
在本例中:
1 2 3 4 5 | var b = [1, 2, 3]; var arrayFunction = function(arr) { arr = ["a","b","c"]; }; arrayFunction(b); |
对象引用本身按值传递。您实际上并没有更改
但是,当您重新指派
记住,在函数中,
所以当你说
但是当你说
在javascript中,一个变量只指向一个数组;因此,如果复制该变量,将得到指向同一数组的两个变量:
1 2 | var a = [1,2,3]; var b = a; |
用
当你写的时候
1 | a = [5, 6, 7]; |
您正在设置
除非您明确要求(例如,使用
实际上,任何值(例如对象)都会发生同样的情况。对于数字和字符串,同样的逻辑也是有效的,但是很难注意到副本和共享同一对象之间的区别,因为数字和字符串不能更改(不可变)。
在其他语言(如C和C++)中,变量包含值,而不是指针;因此,在进行赋值时,例如,对象从一个变量复制到另一个变量,如果需要一个指针,则必须明确地请求它。