赞
踩
function defineProperty(target, key, value) { // 每一个属性定义的时候, 都会有 getter 和 setter Object.defineProperty(target, key, { get () { return value }, set (newVal) { // 在这里面更新值, 且触发视图更新(调用视图更新的方法) console.log('视图更新') value = newVal } }) } // 监听方法 function observe(target) { // 判断不是对象或数组这返回自身 if (typeof target !== 'object' || target === null) { return target } // 重新定义各个属性 for(let key in target) { defineProperty(target, key, target[key]) } } // 视图更新方法 function updateView() { console.log('视图更新') } // 定义数据 const data = { name: '张三', age: 20 } observe(data) data.name = '李四' console.log(data)
function defineProperty(target, key, value) { // 深度监听(递归) observe(value) // 核心 API Object.defineProperty(target, key, { get() { return value }, set(newVal) { // 这只新值 if (newVal !== value) { console.log('更新') // 深度监听 (如果将属性值设置为一个对象, 不再次进行深度监听, 会监听不到更新操作) // 例如: 在下面代码中的 data.info.address.home = '上海' 修改, 如果不在这里进行深度监听, 会监听不到这个操作 observe(newVal) // 赋值 value = newVal // 触发视图更新 updateView() } } }) } function observe(target) { // 判断不是对象或数组这返回自身 if (typeof target !== 'object' || target === null) { return target } // 重新定义各个属性 for(let key in target) { defineProperty(target, key, target[key]) } } // 视图更新方法 function updateView() { console.log('视图更新') } // 定义数据 const data = { name: '张三', age: 20, info: { address: '北京' } } // 监听数据 observe(data) data.info.address = '深圳'; data.info.address = {home: '南京'} data.info.address.home = '上海' data.sex = 'woman'; // 新增属性时, 无法监听到 delete data.age; // 删除属性时, 无法监听到 console.log(data);
// 重新定义自己的数组原型(目的: 为了防止污染全局的 Array 原型) const oldArrayProperty = Array.prototype; // 创建新对象, 原型指向 oldArrayProperty, 再扩展新的方法不会影响原型 const arrProto = Object.create(oldArrayProperty); ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(methodName => { arrProto[methodName] = function () { // 触发视图更新 updateView(); // 数组原本原型中的方法也是需要执行的 oldArrayProperty[methodName].call(this, ...arguments); // 上面语法类似于 Array.prototype.方法名(push/pop 等).call(this, ...arguments) } }) function defineProperty(target, key, value) { // 深度监听(递归) observe(value); // 核心 API Object.defineProperty(target, key, { get() { return value; }, set(newVal) { // 这是新值 if (newVal !== value) { console.log('更新'); // 深度监听 observe(newVal); // 赋值 value = newVal; // 触发视图更新 updateView(); } } }) } function observe(target) { // 判断不是对象或数组这返回自身 if (typeof target !== 'object' || target === null) { return target; } // 判断是数组的话, 则把 target 的原型设置 成 arrProto if(Array.isArray(target)) { target.__proto__ = arrProto; } // 重新定义各个属性 for(let key in target) { defineProperty(target, key, target[key]); } } // 视图更新方法 function updateView() { console.log('视图更新'); } // 定义数据 const data = { name: '张三', age: 20, info: { address: '北京' }, num: [10, 20, 30] } observe(data) data.num.push(40); console.log(data)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。