12 触类旁通多种框架
vue2.x版本数组 monkey pathch(猴子补丁) 方法重写
vue2.x版本将数组的常用方法进行重写,进而覆盖掉原生的数组方法,重写之后的数组方法需要能够被拦截。 实现逻辑:
const arrExtend = Object.create(Array.prototype)
const arrMethods = [
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
]
arrMethods.forEach(method => {
const oldMethod = Array.prototype[method]
const newMethod = functiond(...args){
oldMethod.apply(this, args)
console.log(`${method}方法被执行了`)
}
arrExtend[method] = newMethod
})
JS知识点:
Object.create()
Array.prototype
apply(this, args)
Object.defineProperty和Proxy
用Proxy来完成代码重构,如下:
let data = {
stage: 'GitChat',
course: {
title: '前端开发进阶',
author: ['Lucas'],
publishTime: '2018年5月'
}
}
const observe = data => {
if (!data || Object.prototype.toString.call(data) !== '[Object Object]') {
return
}
Object.keys(data).forEach(key => {
let currentValue = data[key]
// 事实上,Proxy也可以对函数类型进行代理。这里只对承载数据类型的object进行处理,了解即可
if (typeof currentValue === 'object') {
observe(currentValue)
data[key] = new Proxy(currentValue, {
set(target, property, value, receiver) {
// 因为使用数组的push方法时会引起length属性的变化,所以调用push之后会触发两次set操作,我们只需要保留一次即可
if (property !== 'length') {
console.log(`setting ${key} value now, setting value is`, currentValue)
}
return Reflect.set(target, property, value, receiver)
}
})
} else {
Object.defineProperty(data, key, {
enumerable: true,
configurable: false,
get() {
console.log(`getting ${key} value now, getting value is`, currentValue)
return currentValue
},
set(newValue) {
currentValue = newValue
console.log(`setting ${key} value now,setting value is`, currentValue)
}
})
}
})
}
observe(data)
JS知识点:
Object.property()
Object.prototype.toString.call()
new Proxy()
Reflect.set()