tinny declarative

by Zero Yu

HTML

<div></div>

JavaScript

function observe(obj) {
  if (obj === null || typeof obj !== 'object') {
    return
  }
  Object.keys(obj).forEach(prop => {
  	defineReactive(obj, prop, obj[prop])
  })
}

function defineReactive(obj, prop) {
  let val = obj[prop]
  observe(val)
  let dep = new Dep()
  Object.defineProperty(obj, prop, {
    set(newVal) {
      console.log('setter')
      val = newVal
      dep.notify()
    },
    get() {
      if (Dep.target) {
        dep.addSub(Dep.target)
      }
      console.log('getter')
      return val
    }
  })
}

class Dep {
  constructor() {
    this.subs = []
  }
  
  addSub(sub) {
    this.subs.push(sub)
  }
  
  notify() {
    this.subs.forEach(sub => {
      sub.update()
    })
  }
}

class Watcher {
  constructor(obj, prop, cb) {
    Dep.target = this
    this.obj = obj
    this.prop = obj
    this.cb = cb
    this.val = obj[prop]
    Dep.target = null
  }
  
  update() {
    this.cb()
  }
}

const div = document.querySelector('div')
function update() {
  div.innerHTML = data.text
}
var data = { text: 'text' }
observe(data)
new Watcher(data, 'text', update)
data.text = 'text1'