为什么函数中改变的对象会改变它们在内存中指向的内容,但有时会创建一个新的内存对象
Why do objects changed in function change what they point to in memory, but sometimes create a new memory object?
我在这个博客上读到,如果一个对象或数组在函数内部发生了更改,那么所指向的内存中的值也会发生更改,就像在函数外部发生更改一样。
var a = [1,2,3],
b = a;
b[0] = 5;
console.log(a); // [5, 2, 3]
将产生与相同的结果
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];
然而,我不明白的是,为什么在函数内重新分配多个数组值不会改变函数外的值:
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中的对象并不是通过引用传递的。我看到它被称为"通过复制引用传递"或"通过句柄传递"——这两种方法都能更好地描述实际发生的事情。
在本例中:
var b = [1, 2, 3];
var arrayFunction = function(arr) {
arr = ["a", "b", "c"];
};
arrayFunction(b);
对象引用本身是通过值传递的。实际上,您并没有更改b
变量的值。但是,函数参数(arr
)和b
变量最初指向同一个对象,因此如果更改其中一个,则可以通过其中一个引用对象并查看更改。
但是,当将arr
重新指定为指向其他对象时,b
变量仍然指向旧对象,并且不会更改。
请记住,在函数中,arr
不是实际的数组;arr
是指向数组的引用。
因此,当您说arr[0]
时,您正在检索数组,然后获取或更新其中的项目。
但是,当您说arr = ["a","b","c"]
时,您正在创建一个新对象(在右侧),然后将arr
转换为指向新对象的引用。
在Javascript中,变量仅指向数组;因此,如果你复制变量,你会得到两个指向同一数组的变量:
var a = [1,2,3];
var b = a;
使用两个变量都可以观察到用a[0] = 99
改变数组的元素,因为只有一个数组,并且a
和b
都指向它
当你写
a = [5, 6, 7];
您正在将a
设置为指向另一个不同的数组。
Javascript从不复制数组,除非您明确要求它(例如使用b = a.slice()
)。
事实上,任何值(例如对象)都会发生同样的情况。对于数字和字符串,相同的逻辑也是有效的,但很难注意到复制和共享同一对象之间的区别,因为数字和字符串不能更改(它们是"不可变的")。
在C和C++等其他语言中,变量包含值,而不是指针;因此,当进行赋值时,例如,对象从一个变量复制到另一个变量,如果你想要一个指针,你必须明确要求它
- 简单对象的Javascript内存泄漏
- 递归Javascript对象是否会导致任何问题(内存泄漏)
- Javascript:将类/对象引用设置为 NULL,内存中的子对象/类会发生什么
- 是否所有面向对象的语言都会在内存中创建大量重复信息
- javascript删除对象,防止内存泄漏
- 在内存中加载javascript对象的正确方法
- 空的 JavaScript 对象有多少内存
- 如何将内存中的复杂对象写入 nodejs 中的文件
- 如何将非常大的内存中对象保存到文件
- 避免使用 jquery 创建和删除 DOM 的对象发生内存泄漏
- 将文字/对象/类传递给具有数千次调用的函数的内存含义
- 别名 JavaScript 对象会增加内存
- 在函数中创建 jQuery 对象然后不使用它是否会产生内存泄漏
- 对象文字符号与原型速度和内存
- 在浏览器中缓存对象时,内存过多
- 对象1作为对象2的属性,而对象2又是对象1的属性,这将导致内存泄漏
- 使用THRE.JS对象的全局数组的Javascript内存管理
- ID属性为的动态DOM对象的IE9内存泄漏
- 为什么函数中改变的对象会改变它们在内存中指向的内容,但有时会创建一个新的内存对象
- 在Chrome扩展内容脚本中共享内存对象