Created
February 7, 2019 03:33
-
-
Save catc/e5a2f95569cd8b47f4bfecc9280d1ce3 to your computer and use it in GitHub Desktop.
airbnb technical screen
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.clear() | |
class Model { | |
constructor(props = {}){ | |
this.data = props | |
this.silent = {} | |
this.subs = { | |
change: { | |
}, | |
handleChangeAll: [] | |
} | |
} | |
get(key){ | |
return this.data[key] | |
} | |
set(key, val, opts = {}){ | |
const oldVal = this.data[key] | |
// store silent | |
if (opts.silent){ | |
this.silent[key] = true | |
} | |
// trigger event | |
this._trigger(key, oldVal, val) | |
return this.data[key] = val | |
} | |
has(key){ | |
return this.data.hasOwnProperty(key) | |
} | |
unset(key){ | |
const oldVal = this.data[key] | |
this._trigger(key, oldVal, undefined) | |
return delete this.data[key] | |
} | |
_trigger(key, oldVal, newVal){ | |
if (!this.silent[key]){ | |
// trigger all | |
this.subs.handleChangeAll.forEach(sub => sub(key, oldVal, newVal)) | |
// trigger specific keya | |
if (this.subs.change[key] && this.subs.change[key].length){ | |
this.subs.change[key].forEach(sub => sub(oldVal, newVal)) | |
} | |
} | |
} | |
on(event, fn){ | |
let [eventName, key] = event.split(':') | |
if (key){ | |
const subs = this.subs[eventName][key] | |
if (!subs){ | |
this.subs[eventName][key] = [] | |
} | |
this.subs[eventName][key].push(fn) | |
} else { | |
// catch all | |
this.subs.handleChangeAll.push(fn) | |
} | |
} | |
} | |
const person = new Model({ name: 'auster', age: 27 }); | |
console.log(person.get('name')); // auster | |
console.log(person.get('age')); // 27 | |
person.set('job', 'engineer'); | |
// console.log(person.get('job')); // engineer | |
const dog = new Model(); | |
dog.set('name', 'ruffy'); | |
console.log(dog.get('name')); // ruffy | |
console.log(dog.has('age')); // false | |
dog.set('age', 10, { silent: true }); | |
console.log(dog.has('age')); // true | |
dog.unset('name'); | |
console.log(dog.has('name')); // false | |
console.log('---------') | |
person.on('change', function (attr, oldValue, newValue) { | |
console.log(`${attr} has changed from ${oldValue} to ${newValue}`); | |
}); | |
person.on('change', function (attr, oldValue, newValue) { | |
console.log(`${attr} has changed from ${oldValue} to ${newValue}`); | |
}); | |
person.on('change:name', function(oldValue, newValue) { | |
console.log(`specifically name changed from ${oldValue} to ${newValue}`); | |
}); | |
person.set('name', 'kevin'); | |
// name has changed from auster to kevin | |
// name has changed from auster to kevin | |
// specifically name has changed from auster to kevin | |
person.set('height', 10); | |
// height has changed from undefined to 10 | |
// height has changed from undefined to 10 | |
dog.on('change:age', function() { | |
throw new Error('this code should not run'); | |
}); | |
dog.set('age', 20); | |
person.unset('name'); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment