Vue 响应式原理
ES5
var data = {
name: 'Jack Wang',
age: 21,
salary: 3500,
array: ['Jack', 'should', 'fighting']
}
function render() {
console.log('render')
}
var method = ['push', 'pop', 'unshift', 'shift', 'reverse', 'sort', 'splice']
var arrayProto = Array.prototype
var proto = Object.create(arrayProto)
method.forEach(function(method) {
proto[method] = function() {
var res = arrayProto[method].call(this, ...arguments)
render()
return res
}
})
function observe(obj) {
if (!obj || typeof obj !== 'object') {
return
}
if (Array.isArray(obj)) {
obj.__proto__ = proto
return
}
Object.keys(obj).forEach(function(key) {
defineReactive(obj, key, obj[key])
})
}
function defineReactive(obj, key, value) {
observe(value)
Object.defineProperty(obj, key, {
get: function() {
console.log('get')
return value
},
set: function(newValue) {
console.log('set', newValue)
observe(newValue)
if (newValue !== value) {
value = newValue
render()
}
}
})
}
observe(data)
ES6 Proxy
var data = {
name: 'Jack Wang',
age: 21,
salary: 3500,
array: ['Jack', 'will', 'be', 'the', 'best']
}
function render(params) {
console.log('render')
}
var handler = {
get(target, key) {
console.log('get')
if (typeof target[key] === 'object' && target[key] !== null) {
return new Proxy(target[key], key)
}
return Reflect.get(target, key)
},
set(target, key, value) {
console.log('set', value)
if (key === 'length') {
return
}
Reflect.set(target, key, value)
render()
}
}
var proxy = new Proxy(data, handler)