Skip to content

Instantly share code, notes, and snippets.

@barbinbrad
Last active May 13, 2022 14:16
Show Gist options
  • Select an option

  • Save barbinbrad/34f564ebe24832f2f5c4416bf8df0717 to your computer and use it in GitHub Desktop.

Select an option

Save barbinbrad/34f564ebe24832f2f5c4416bf8df0717 to your computer and use it in GitHub Desktop.
Reactivity in javascript
function observe (obj) {
if (Object.prototype.toString.call(obj) !== '[object Object]') {
throw new TypeError()
}
Object.keys(obj).forEach(key => {
let internalValue = obj[key]
let dep = new Dependencies()
Object.defineProperty(obj, key, {
get () {
dep.subscribe()
return internalValue
},
set (newValue) {
const isChanged = internalValue !== newValue
if (isChanged) {
internalValue = newValue
dep.publish()
}
}
})
})
}
class Dependencies {
constructor () {
this.subscribers = new Set()
}
subscribe () {
if (activeUpdate) {
// register the current active update as a subscriber
this.subscribers.add(activeUpdate)
}
}
publish () {
// run all subscriber functions
this.subscribers.forEach(subscriber => subscriber())
}
}
let activeUpdate
function reactive (update) {
function wrappedUpdate () {
activeUpdate = wrappedUpdate
update()
activeUpdate = null
}
wrappedUpdate()
}
let state = {
count: 0
}
observe(state)
reactive(() => {
console.log(`Twice the count is ${state.count * 2}`)
})
reactive(() => {
console.log(`Half the count is ${state.count / 2}`)
})
state.count++
// console: Twice the count is 2
// console: Half the count is 0.5
state.count++
// console: Twice the count is 4
// console: Half the count is 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment