JS系列之参数是值传递还是引用传递?

164 阅读2分钟

首先给出结论

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

image.png

当foo(value)时,其实拷贝的是value的值1给foo中的形参v 如下图所示

image.png

问题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都是引用数据类型 保存的值是其对象的地址

image.png

当foo(obj)时,将obj的值传递给了foo的形参o,此时obj和o的值都是0x4444,他们指向同一个地址,如下图所示

image.png

修改o.value=2 图如下所示

image.png

所以obj.value的值也变成了2

问题3:

var obj = {
    value: 1
};
function foo(o) {
    o = 2;
    console.log(o); //2
}
foo(obj);
console.log(obj.value) // 1

图解: image.png

当foo(obj)时,将obj的值传递给了foo的形参o,此时obj和o的值都是0x4444,他们指向同一个地址,如下图所示

image.png

不同的时,这是修改 o=2 ,o的内容不再是0x4444,而是变成了2,这是obj.value=1 如下图所示

image.png

参考: