000 学习vue源码里面一些处理技巧
1函数的拦截
1使用一个临时变量存储原来函数;2重新定义原来函数;3扩展原来函数功能;4原函数执行(注意绑定this)。
更高级的做法是面向切片编程AOP
//1 重新定义内置函数 // 重写log方法 比如说只在开发环境下打印日志 const OriginLog = console.log // 使用一个临时变量OriginLog存储函数 原始log方法里面的this可是console对象。是因为console.log console.log = function () { //重新定义原来的函数 if (process.env.NODE_ENV === 'development') { //定义扩展的功能 OriginLog.apply(console, arguments) //调用临时的函数,注意绑定this } } //2 自定义函数 function func() { console.log('原始的功能'); } const originFunc = func //临时变量存储原函数 func = function () { //重新端定义函数的函数 console.log('新加的功能', this); //扩展新的功能 originFunc.apply(this, arguments) //原函数执行 console.log('也有可能在原函数之后调用执行,都可以'); } func()
应用1:vue响应式的时候对改变数组7个方法的拦截
// vue扩展数组的方法:修改要进行响应式化的数组原型(__proto__); //默认 arr => Array.prototype->Object.prototype->null; arr.__proto__.__proto__.__proto__ =null // 加一层原型链 arr->AAA->Array.prototype->Object.prototype->null(定义一个空对象AAA,但是AAA.__proto__=Array.prototype,这就自然用到了Object.create)
const ARRAY_METHODS = ['push', 'pop', 'shift', 'unshift', 'sort', 'reverse', 'splice'] const array_methods = Object.create(Array.prototype) //array_methods=AAA 是个空对象但是AAA. __proto__=Array.prototype ARRAY_METHODS.forEach(method => { array_methods[method] = function () { //给这个空对象身上挂载数组的7个变异方法 console.log(`数组${method}方法被拦截了`); //这里做数组响应的逻辑 // 调用原来的方法 Array.prototype[method]原来的方法 let res = Array.prototype[method].apply(this, arguments) return res } }) const arr = [] //只对要响应式化的数组实例进行改变 也就是如下的arr.__proto__=array_methods arr.__proto__ = array_methods