Open Silencer-1984 opened 3 years ago
Proxy对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义。target代表需要添加代理的对象,handler用来自定义对象中的操作,比如可以用来自定义set或者get函数。注意Proxy是生成代理对象,原对象改变不触发handler。
let onWatch = (obj, setBind, getLogger) => { let handler = { get(target, property, receiver) { getLogger(target, property) return Reflect.get(target, property, receiver) // 获取最新值 }, set(target, property, value, receiver) { setBind(value, property) return Reflect.set(target, property, value) // 获取最新值 } } return new Proxy(obj, handler) }
let obj = { a: 1 } let p = onWatch( obj, (v, property) => { console.log(监听到属性${property}改变为${v}) }, (target, property) => { console.log('${property}' = ${target[property]}) } ) p.a = 2 // 监听到属性a改变 p.a // 'a' = 2
监听到属性${property}改变为${v}
'${property}' = ${target[property]}
在上述代码中,我们通过自定义set和get函数的方式,在原本的逻辑中插入了我们的函数逻辑,实现了在对对象任何属性进行读写时发出通知。 当然这是简单版的响应式实现,如果需要实现一个 Vue 中的响应式,需要我们在get中收集依赖,在set派发更新,之所以 Vue3.0 要使用Proxy替换原本的 API 原因在于Proxy无需一层层递归为每个属性添加代理,一次即可完成以上操作,性能上更好,并且原本的实现有一些数据更新不能监听到,但是Proxy可以完美监听到任何方式的数据改变,唯一缺陷可能就是浏览器的兼容性不好了 ### reduce reduce有两个参数,回调函数(callback)和初始值(initialValue),其中回调函数一共有四个参数Accumulator (acc) (累计器,初始值是initialValue,若没有则为数据第一个索引)Current Value (cur) (当前值)Current Index (idx) (当前索引)Source Array (src) (源数组) 打断reduce的方法,可以运用在map、filter、forEeach ```javascript const array = ['9', '91', '95', '96', '99']; const x = array .slice(0) // 复制一个新数组,防止影响原数组。 .reduce((acc, curr, i, arr) => { if (i === 2) arr.splice(1); // 直接截取原数组的方式打断循环。 return (acc += curr); }, '');
ES Module与CommonJS区别
Proxy
Proxy对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义。target代表需要添加代理的对象,handler用来自定义对象中的操作,比如可以用来自定义set或者get函数。注意Proxy是生成代理对象,原对象改变不触发handler。
let obj = { a: 1 } let p = onWatch( obj, (v, property) => { console.log(
监听到属性${property}改变为${v}
) }, (target, property) => { console.log('${property}' = ${target[property]}
) } ) p.a = 2 // 监听到属性a改变 p.a // 'a' = 2