/**
* 响应式 - 数据变了会更新视图
*/
function updateView() {
console.log('更新视图')
}
let oldArrayPrototype = Array.prototype
let proto = Object.create(oldArrayPrototype)
;['push', 'shift', 'pop', 'unshift', 'splice'].forEach(method => {
proto[method] = function(params) {
// 改写方法,但是还是要调用老的方法实现功能
updateView()
oldArrayPrototype[method].call(this, ...arguments)
}
})
function observer(target) {
if (typeof target !== 'object' || target == null) {
return target
}
if (Array.isArray(target)) { // 拦截数组,给数组的原型方法
target.__proto__ = proto
}
for (const key in target) {
if (target.hasOwnProperty(key)) {
defineReactive(target, key, target[key])
}
}
}
function defineReactive(target, key, value) {
observer(value)
Object.defineProperty(target, key, {
get() {
return value
},
set(newValue) {
if (newValue !== value) {
updateView()
value = newValue
}
}
})
}
let data = {
name: 'tom',
age: {
n: 100
},
children: [1, 2.3, 4]
}
// 利用Object.definePrototype 观察数据
observer(data)
// data.name = 'jack'
// data.age.n = 300
data.children.push(500) // push pop unshift shift reverse sort splice
Vue2 数据劫持原理
于 2024-07-09 16:08:40 首次发布