# 前置
元编程:把代码作为数据,通过字符串/AST去操作数据,使代码可以根据不同条件变化,JS中常见的使用方式是eval()、new Function()
# 1. 简单实现一个响应式函数,对一个对象内的key添加响应式
const data = {
a: 1,
b: 2,
c: {
c1: 3
c2: {
cc: 4
}
}
}
输入:data.a = 'a'
输出:Set key=a value=a
输入:console.log(data.a)
输出:Get key=a value=a
const render = (key, value) => {
console.log('Set key=${key} value=${value}');
}
const reactiveProperty = (key, Obj) => {
reactive(pbj);
Object.defineProperty(key, Obj, (
get(){
return Obj.key
};
set(){
if(Obj.value === value){
return
}
Obj.value = value
}
render(key, value)
))
}
const reactive = (obj) => {
if(typeof obj === 'Object'){
for(Obj in Obj){
reactiveProperty(Obj)
}
}
}
## 2\. Vue对于数组的操作,怎么确定当前操作数组的方法
``js
// 拦截数组方法
const arrayProto = Array.prototype;
export const arrayMethods = Object.create(arrayProto);
['push','pop','shift','unshift','splice','sort','reverse'].forEach(method => {
const original = arrayProto[method]
Object.defineProperty(arrayMethods, method, {
value: function mutator(...args){
return original.apply(this.args)
},
enumerable: false,
writable: true,
configurable: true
})
})
## 3\. Vue对于删除的操作(实现一个基于proxy的响应式,能监听基于删除的操作)
function makeObserver(target){
let handlerName = Symbol('handler');
observerStore.set(handlerName, []);
target.observe = function(handler) {
observerStore.get(handlerName.push(handler))
};
const proxyHandler = {
get(target, property, receiver) {
let success = Reflect.get(...arguments);
if(success){
observerStore.get(handlerName).forEach(handler => handler('Get', property, target[property]))
}
return success;
},
set(target, property, value, receiver) {
let success = Reflect.get(...arguments);
if(success){
observerStore.get(handlerName).forEach(handler => handler('Get', property, target[property]))
}
return success;
},
deleteProperty(target, property, value, receiver) {
let success = Reflect.deleteProperty(...arguments);
if(success){
observerStore.get(handlerName).forEach(handler => handler('Get', property, target[property]))
}
return success;
},
}
}
let user = {};
user = makeObserver(user);
user.Observe((action, key, value) => {
console.log('${action} key=${key} value=${value || ''}');
})
输入:data.a = 'a'
输出:Set key=a value=a
输入:console.log(data.a)
输出:Get key=a value=a
输入:delete data.a = 'a'
输出:DELETE key=a value=