一:值类型(基本数据类型) :
栈中存储数据, 赋值拷贝的是数据,修改拷贝后的数据对原数据没有影响。
二:引用类型(复杂数据类型array、function、object)
栈中存储地址,堆中存储数据。赋值拷贝的是地址,修改拷贝后的数据对原数据有影响。(拷贝地址后指向堆中的一个值)
//1.值类型
let num1 = 10
let num2 = num1 //拷贝数据
num2 = 100
console.log(num1, num2); //10 100
//2.引用类型
let arr1 = [10, 20, 30]
let arr2 = arr1 //操作栈,拷贝栈地址,两个变量共用一个堆
arr1[0] = 100 //修改堆数据
console.log(arr1, arr2); //[100,20,30] [100,20,30]
arr2 = 66 //先销毁了arr2中储存的地址,再对变量重新赋值
console.log(arr1); //[100,20,30]
/*变量在赋值的时候,要仔细观察拷贝的是栈地址还是堆数据
(1)拷贝地址:修改数据会对原数据"有影响"
(2)拷贝堆数据:修改数据对原数据无影响*/
let num = arr1[0]
num = 200
console.log(arr1); //[100,20,30] 拷贝的是堆数据
let obj = {
name: '佩奇',
age: 2
}
let name = obj.name
name = '乔治'
console.log(obj.name); //佩奇 拷贝的是堆数据
注意点:一定要看清楚,你的语法到底是操作栈,还是操作堆
如何区分引用类型,到底是改栈还是堆呢? 就看他是操作变量自己,还是操作变量元素/属性
修改栈(不会对别人产生影响): 变量名 = 值
修改堆(会对别人产生影响): 数组名[下标] = 值 对象名.属性值 = 值
引申问题:函数传参时,传值类型和引用类型有什么区别?
函数传参时,传值类型:实参传递给形参,传递的是栈里面的数据,相当于将实参的数据赋值给变量形参,当形参发生改变时,相当于重新赋值,修改形参不会影响实参;
传引用类型:将实参栈里面的地址拷贝给变量形参,二者共用堆里面的数据,当修改形参的数据,堆里面的数据就会改变,从而影响实参.