1.值类型与引用类型
1.1. 了解下内存知识
这里涉及到浏览器的内存原理,内存空间分为栈空间和堆空间
- 栈空间:占很小空间,存储速度极快,效率很高,只能存少量数据
- 堆空间:占很大空间,存储没有限制,效率较低
1.2. 具体分析
js数据类型有很多种,分为两大类
- 值类型(简单数据类型):字符串、数字、布尔、undefined、null 栈中存储的是数据,赋值拷贝的也是数据。修改拷贝后的数据,对原数据没有影响
- 引用类型(复杂数据类型):数组、函数、对象 栈中存储的是地址,数据存在堆中。赋值拷贝的是地址,修改拷贝后的数据对原数据有影响
对简单数据类型时,赋值是直接在栈中储存,对复杂数据类型来说,是把数据在堆中存储的地址赋值给变量存在栈中,栈中存的是地址
// 值类型
let num1 = 10,
num2 = num1
num2 = 100
console.log(num1, num2) // 10 100 赋值后源值没变
//引用类型
let arr1 = [10, 20, 30],
arr2 = arr1
arr2[0] = 100
console.log(arr1, arr2) //[100,20,30] [100,20,30] 赋值后源值变了
let 只能在栈中开启一个变量的内存空间,变量名只能操作栈空间
变量名、数组名、函数名、对象名都存在栈中,数组的中括号[]决定数据存在堆中,函数的function决定函数存在堆中,对象的大括号{}决定对象存在堆中
let arr3 = [10, 20],
arr4 = [10, 20]
console.log(arr3 == arr4) //false 复杂数据类型比较时,比的是地址,地址不同不相等
只有数组通过赋值时两个数组才相等,赋的值是地址,两个数组地址相等
1.3. undefined与null
- 只定义变量名不赋值,会开辟一个内存空间,占据栈空间,打印undefined
- null是一个表示"无"的对象(空对象指针)会占据一定的堆空间和栈空间
- [ ]空数组(有一个length=0存在堆中)和{ }空对象都占据一定的堆空间
null一定是手动增加的,不可能会 自动出来的,其他没有值得都是undefined,使用null的情况:
- 用来初始化一个变量,这个变量可能赋值为一个对象
- 用来和一个已经初始化的变量比较,这个变量可以也可以不是一个对象
- 当函数的参数期望是对象时,用作参数传入
- 当函数的返回期望值是对象时, 用作返回值传出
返回为undefined的情况(表示此处应该有一个值,但是还未定义)
- 变量定义了还没赋值
- 没有返回值的函数(也没有执行结果)
- 没有实参的形参,实参默认为undefined
- 取数组空元素或者对象里面的空属性名(不存在)
- 三元表达式后面的代码1或者代码2没有结果