响应式定义

响应式就是数据模型发生变化能够收回相应响应, 比方调用一个函数

性能实现

vue广泛走的是数据劫持形式, 不同在于vue2应用object.defineproperty,vue3应用的是proxy.也就是一次一个属性劫持,还是一次劫持一个对象.
proxy/reflect是es2015标准中退出的, proxy能够更好地拦挡对象,而reflect能够更优雅的操作对象

proxy/reflect的劣势

  • 针对整个对象定制, 而不是对象的某个属性, 所以不须要进行key值遍历
  • 反对数组, 省去了重载数组办法的hack过程
  • proxy的第二个参数由13种拦挡办法,
  • 能够通过递归不便的进行对象嵌套
应用defineproperty进行对象劫持
let effectivefunction effect(fun) {    effective = fun}function reactive(data) {    if (typeof data !== 'object' || data === null) {        return data    }    Object.keys(data).forEach(function (key) {        let value = data[key]        // 递归调用~~~~        reactive(value)        Object.defineProperty(data, key, {            emumerable: false,            configurable: true,            get: () => {                return value            },            set: newVal => {                if (newVal !== value) {                    effective()                    value = newVal                }            }        })    })    return data}
vue2 数组函数劫持
function hashArray(data) {    const oldArrayPrototype = Array.prototype    const proto = Object.create(oldArrayPrototype);    ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(method => {        // 函数劫持        proto[method] = function () {            effective()            console.log('批改数组的值')            oldArrayPrototype[method].call(this, ...arguments)        }    })    data.__proto__ = proto}
proxy (vue3)

新版的vue3应用es6的proxy形式来解决这个问题,
首先proxy是反对数组的也就是数组是不须要做特地的解决.
对于深层监听也不须要应用递归的形式解决.当get是判断值为对象做响应式解决返回就能够了.比vue2大大的晋升了性能

function reactive(data) {    if (typeof data !== 'object' || data === null) {        return data    }    const observed = new Proxy(data, {        get(target, key, receiver) {            // Reflect有返回值不报错            let result = Reflect.get(target, key, receiver)            // 多层代理            return typeof result !== 'object' ? result : reactive(result)         },        set(target, key, value, receiver) {            effective()            // proxy + reflect            const ret = Reflect.set(target, key, value, receiver)            return ret        },        deleteProperty(target,key){            const ret = Reflect.deleteProperty(target,key)            return ret        }    })    return observed}