前言
我最近在写 Vue 进阶的内容。在这个过程中,有些人问我看 Vue 源码需要有哪些准备吗?所以也就有了这篇计划之外的文章。
当你想学习 Vue 源码的时候,需要有扎实的 JavaScript 基础,下面罗列的只是其中的一部分比较具有代表性的知识点。如果你还不具备 JavaScript 基础的话,建议不要急着看 Vue 源码,这样你会很容易放弃的。
我会从以下 7 点来展开:
- Flow 基本语法
- 发布/订阅模式
- Object.defineProperty
- ES6+ 语法
- 原型链、闭包
- 函数柯里化
- event loop
必要知识储备
需要注意的是这篇文章每个点不会讲的特别详细,我这里就是把一些知识点归纳一下。每个详细的点仍需自己花时间学习。
Flow 基本语法
相信看过 Vue、Vuex 等源码的人都知道它们使用了 Flow 静态类型检查工具。
我们知道 JavaScript 是弱类型的语言,所以我们在写代码的时候容易出现一些始料未及的问题。也正是因为这个问题,才出现了 Flow 这个静态类型检查工具。
这个工具可以改变 JavaScript 是弱类型的语言的情况,可以加入类型的限制,提高代码质量。
// 未使用 Flow 限制function sum(a, b) { return a + b;}// 使用 Flow 限制 a b 都是 number 类型。function sum(a: number, b:number) { return a + b;}复制代码
基础检测类型
Flow 支持原始数据类型,有如下几种:
booleannumberstringnullvoid( 对应 undefined )复制代码
在定义变量的同时在关键的地方声明类型,使用如下:
let str:string = 'str';// 重新赋值str = 3 // 报错复制代码
复杂类型检测
Flow 支持复杂类型检测,有如下几种:
ObjectArrayFunction自定义的 Class复制代码
需要注意直接使用 flow.js,JavaScript 是无法在浏览器端运行的,必须借助 babel 插件,vue 源码中使用的是 babel-preset-flow-vue 这个插件,并且在 babelrc 进行配置。
详细的 Flow 语法可以看以下资料:
这里推荐两个资料
- 官方文档:flow.org/en/
- Flow 的使用入门:zhuanlan.zhihu.com/p/26204569
发布/订阅模式
我们知道 Vue 是内部是实现了双向绑定机制,使得我们不用再像从前那样还要自己操作 DOM 了。
其实 Vue 的双向绑定机制采用数据劫持结合发布/订阅模式实现的: 通过 Object.defineProperty() 来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
我发现有的人把观察者模式和发布/订阅模式混淆一谈,其实订阅模式有一个调度中心,对订阅事件进行统一管理。而观察者模式可以随意注册事件,调用事件。
我画了一个大概的流程图,用来说明观察者模式和发布/订阅模式。如下
这块我会在接下的文章中详细讲到,这里先给出一个概念,感兴趣的可以自己查找资料,也可等我的文章出炉。
其实我们对这种模式再熟悉不过了,但可能你自己也没发现:
let div = document.getElementById('#div');div.addEventListener('click', () => { console.log("div 被点击了一下")})复制代码
可以思考下上面的事件绑定执行的一个过程,你应该会有共鸣。
函数柯里化
数据双向绑定基础:Object.defineProperty()
一、数据属性
数据属性包含一个数据值的位置。这个位置可以读取和写入值。数据属性有 4 个描述他行为的特性:
属性描述Configurable能否用 delete 删除属性从而重新定义属性。默认为 trueEnumerable能否通过 for-in 遍历,即是否可枚举。默认为 trueWritable是否能修改属性的值。默认为 trueValue包含这个属性的数据值,读写属性的时候其实就在这里读写。默认为 undefined
如果你想要修改上述 4 个默认的数据属性,就需要使用 ECMAScript 的 Object.defineProperty() 方法。
该方法包含3个参数:属性所在的对象,属性名,描述符对象。描述符对象的属性必须在上述 4 个属性中。
var person = { name: '',};// 不能修改属性的值Object.defineProperty(person, "name