JS数据类型在vue框架源码中的应用 | 青训营

92 阅读3分钟

vue 框架中,处理代码前,通常会生成上下文对象,利用对象之间的传递赋值特性,可以更方便的书写代码

而此笔记来正自于笔者在手写 vue 源码时,忘记了 JS 中的数据类型,导致很多地方不理解

JS 中的数据类型分为基本数据类型引用数据类型,变量赋值也分为深拷贝和浅拷贝

基本数据类型又叫做基本数据类型或者值类型,引用数据类型又叫做复杂类型

堆栈

堆栈分配的区别:

  • 栈:存储值类型,由操作系统自动分配释放存放函数的参数值、局部变量等,操作方式类似于数据结构中的栈
  • 堆:存储引用类型,一般由程序员分配释放,如果程序员不释放,由垃圾回收机制回收

示例:

 let num = 10
 let obj = { age: 18 }
 let obj2 = obj

值类型

所谓的简单数据类型/值类型指的是:在存储时,变量中存储的是值本身,JS 中的值类型有以下:

  1. string
  2. number
  3. boolean
  4. undefined
  5. null

题目:

 let num1 = 10
 let num2 = num1
 num2 = 20
 console.log(num1) // 10

num1 声明赋值后在栈区开辟了一个空间,将 let num2 = num1 的意思是将 num1赋值给 num2,即 num2 的声明赋值重新在栈区开辟了空间

引用数据类型

所谓的复杂数据类型/引用类型指的是:在存储时,变量中存储的仅仅是地址(引用) ,因此叫做引用数据类型,在 JS 中,任意一个可以 用 new 关键字创建的对象都是引用数据类型,例如;

  1. Obejct
  2. Array
  3. Date
  4. ...
 let obj1 = {
   age: 18
 }
 let obj2 = obj1
 obj2.age = 20
 console.log(obj1.age) // 20

引用数据类型在栈区存储的是其在堆区的地址,也就是说 let obj2 = obj1 是将 obj1 的地址分配给了 obj2obj1 最初的值 { age: 18 } 是存储到堆区的。

同理,将引用数据类型作为函数参数传递,当函数内部对其操作时,也会改变原先的引用类型数值:

 let a = [0, 1, 2, 3]
 function addItem(arr) {
   arr[4] = 4
 }
 addItem(a)
 console.log(a) // [0, 1, 2, 3, 4]

注意点

浏览器环境和 node 环境

浏览器控制台执行顺序和 nodejs 环境下不一样,例如以下代码在浏览器和 node 中打印结果不同

 let a = [0, 1, 2, 3]
 // 先打印
 console.log(a)
 // 再调用函数
 addItem(a)
 function addItem(arr) {
   arr[4] = 4
 }

在浏览器中,打印的工作是靠后执行的,也就是说先执行了 addItem 函数,再打印,所以浏览器结果是:

而 node 则是按正常顺序:

转存失败,建议直接上传图片文件

引用类型赋值

前面讲过两个引用类型赋值其实是地址的传递,不会开辟新的内存,但如果我们赋一个新值,还是会额外开辟内存的:

let obj1 = { name: 'xj', age: 18 }
console.log(obj1.age) // 18
let obj2 = obj1
obj2.age = 19
console.log(obj1.age) // 19
// 赋一个新值,此时不会修改 obj1
obj2 = { name: 'xjj', age: 20 }
console.log(obj1.age) // 19

另外,数组中的某些方法和赋值的结果也不相同,例如:

let obj = { arr: [1111] }

let arr = obj.arr
// 1. 这个操作不会修改 obj
arr = [1111, 2222]
console.log(obj.arr) // [1111]

let arr2 = obj.arr
// 2. push 操作会修改 obj
arr2.push(2222)
console.log(obj.arr) // [1111, 2222]