阅读前提
- JS6的变量类型分为两大类七种,六种简单数据类型(原始类型、原始值)Undefined、Null、Boolean、Number、String、Symbol和一种复杂数据类型Object.
- 内存划分为栈*(stack)和堆(heap)*,栈是先进后出,静态,速度快,确定后不可变;堆是动态,运行时确定,速度慢.
变量的复制
因为简单数据类型的内容在赋值后是确定的,因此都存放在栈中,而对象需要更改方法,属性,所需空间是不确定的,所以存放在堆中.
但变量都是存放在栈中的;堆中存放的是对象实体.
所以,两个简单数据类型的复制是把值给操作数,因为变量的内容一样是存储在栈中;
而复杂数据类型变量在栈中存储的是 指向堆的指针 ,所以复杂数据类型的复制是引用访问,当复制复杂数据类型时,更改其中一个对象的方法,另一个也会改变.
将a复制给b时,a的值会复制给b,将对象person复制给human时,person所保存的地址会复制给human.
此时更改a的值,b不会有任何影响,因为二者在栈中是相互独立的,只是将a的内容给b而已;
但若更改person的方法或属性,human也会改变,因为两者保存的是一个相同的地址,指向堆中同一个对象.
函数的参数传递
函数的参数传递只有值传递这一种
简单数据类型传参
/*demo 1*/
function add(num) {
num += 10;
return num;
}
let count = 20;
let result = add(count);
alert(count); //20 没变化
alert(result); //30 结果变化
count传入函数后只是将局部变量num值和count相同而已,函数的操作变化对count没有任何影响.(值传递)
function setName(obj) {
obj.name = "Jack";
obj = new object();
obj.name = "Lucy";
}
let person = new object();
setName(person);
alert(person.name); //输出为Jack
同理,person传入局部变量obj的是地址,两个变量指向同一个对象,所以obj第一次更改name属性person也会变化;
而当obj重新分配对象时,两个变量person和obj所保存的内容(地址)就不相同了,重新更改obj的name属性后person不会改变,而当函数结束后,作为局部变量的obj就会被释放.(值传递)