js 基本类型和引用类型的区别

基本类型和引用类型

JavaScript 规定了 7 钟原始数据类型,他们分别是:

基本类型(6):undefined、null、number、string、boolean、symbol(ES6 新引入)

引用类型(1):object

基本类型指的是简单的数据段,而引用类型指那些可能由多个值构成的对象。

他们的最大区别在于:

基本类型赋值给其他变量时,修改其他变量的值,不会影响原始值;而引用变量则会改变。

通过下面的小栗子,你可以更直观地感受:

// 基本类型
var num1 = 5
var num2 = num1
num2 = 8
console.log(num1)  // 5
console.log(num2)  // 8
// 引用类型
var obj1 = { a: 5, b: 6 }
var obj2 = obj1
obj2.a = 8
console.log(obj1.a)  // 8
console.log(obj2.a)  // 8

好奇如我,为何 JavaScript 要这么做?

都像基本类型多好,也符合我们的认知,偏偏要弄出个引用类型,消耗脑细胞。

其实,这是因为,对象(Object)的大小不固定。

对于一个很大的 Object,如果每次将它赋值给一个新的变量,都重新分配一个新的内存空间,对于性能损耗是很大的。

堆和栈

这便引出了 JS 中,基本类型和引用类型的数据保存机制:

  • 基本类型:占据内存空间大小固定,存放在栈内存(Stack),按值来访问。

  • 引用类型:占据内存空间大小不固定,存放在堆内存(Heap),并由栈内存(Stack)中存放指向该堆内存(Heap)的地址,按引用访问。

你可以这么理解:

基本类型就像现金,引用类型就像存折

下图可助你进一步理解

深拷贝和浅拷贝

那么问题来了,我就想 Object 也想基本类型一样,可以吗?

可以呀!自己写个函数来实现。

实现思路就是:

递归调用,把所有属于对象的属性类型都遍历赋给另一个对象即可。

function deepClone(obj = {}) {
   if (typeof obj !== 'object' || obj == null) {
       return obj
  }
   // 初始化返回结果
   let result
   if (obj instanceof Array) {
       result = []
  } else {
       result = {}
  }

   for (let key in obj) {
       if (obj.hasOwnProperty(key)) {
           // 递归调用
           result[key] = deepClone(obj[key])
      }
  }

   return result
}

typeof 和 instanceof 的区别

posted @ 2019-12-11 20:11  吾儿滨滨  阅读(235)  评论(0)    收藏  举报