首先给出结论
JS中参数是按值传递 ,基本数据类型传递的是值,而引用类型传递的值是指针,指向其在堆中开辟的对象 JS中基本类型是存放在栈 中的 (不包含闭包中的变量,闭包中的变量存放在堆上)
JS中引用类型是存放在堆中的,更准确的说是其指针(内存地址又或者叫引用)存放在栈中,而指针指向的那个对象是开辟在堆内存中的
- 栈:基本数据类型(Undefined、Null、Boolean、Number、String、Symbol、BigInt)
- 堆:引用数据类型(对象、数组和函数)
思考下面问题:
问题1:
var value = 1;
function foo(v) {
v = 2;
console.log(v); //2
}
foo(value);
console.log(value) // 1
图解:value是基本数据类型放在栈中内存地址是Ox1111,foo保存的是指向堆中的foo对象的地址ox33333
当foo(value)时,其实拷贝的是value的值1给foo中的形参v 如下图所示
问题2:
var obj = {
value: 1
};
function foo(o) {
o.value = 2;
console.log(o.value); //2
}
foo(obj);
console.log(obj.value) // 2
图解:注意obj和foo都是引用数据类型 保存的值是其对象的地址
当foo(obj)时,将obj的值传递给了foo的形参o,此时obj和o的值都是0x4444,他们指向同一个地址,如下图所示
修改o.value=2 图如下所示
所以obj.value的值也变成了2
问题3:
var obj = {
value: 1
};
function foo(o) {
o = 2;
console.log(o); //2
}
foo(obj);
console.log(obj.value) // 1
图解:
当foo(obj)时,将obj的值传递给了foo的形参o,此时obj和o的值都是0x4444,他们指向同一个地址,如下图所示
不同的时,这是修改 o=2 ,o的内容不再是0x4444,而是变成了2,这是obj.value=1 如下图所示
参考: