Vue2 数据劫持原理

/**
 * 响应式 - 数据变了会更新视图
 */

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

你可能感兴趣的:(前端框架)