你知道值类型与引用类型的区别吗?

187 阅读3分钟

1.值类型与引用类型

1.1. 了解下内存知识

这里涉及到浏览器的内存原理,内存空间分为栈空间和堆空间

  • 栈空间:占很小空间,存储速度极快,效率很高,只能存少量数据
  • 堆空间:占很大空间,存储没有限制,效率较低

1.2. 具体分析

js数据类型有很多种,分为两大类

  1. 值类型(简单数据类型):字符串、数字、布尔、undefined、null 栈中存储的是数据,赋值拷贝的也是数据。修改拷贝后的数据,对原数据没有影响
  2. 引用类型(复杂数据类型):数组、函数、对象 栈中存储的是地址,数据存在堆中。赋值拷贝的是地址,修改拷贝后的数据对原数据有影响

对简单数据类型时,赋值是直接在栈中储存,对复杂数据类型来说,是把数据在堆中存储的地址赋值给变量存在栈中,栈中存的是地址

         // 值类型
         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存在堆中)和{ }空对象都占据一定的堆空间
  1. null一定是手动增加的,不可能会 自动出来的,其他没有值得都是undefined,使用null的情况:

    • 用来初始化一个变量,这个变量可能赋值为一个对象
    • 用来和一个已经初始化的变量比较,这个变量可以也可以不是一个对象
    • 当函数的参数期望是对象时,用作参数传入
    • 当函数的返回期望值是对象时, 用作返回值传出
  2. 返回为undefined的情况(表示此处应该有一个值,但是还未定义)

    • 变量定义了还没赋值
    • 没有返回值的函数(也没有执行结果)
    • 没有实参的形参,实参默认为undefined
    • 取数组空元素或者对象里面的空属性名(不存在)
    • 三元表达式后面的代码1或者代码2没有结果