Skip to content

Instantly share code, notes, and snippets.

@synzhang
Last active December 9, 2016 10:09
Show Gist options
  • Save synzhang/da981ebff525d6927bfbd23673a14fe4 to your computer and use it in GitHub Desktop.
Save synzhang/da981ebff525d6927bfbd23673a14fe4 to your computer and use it in GitHub Desktop.
OLOO(Objects linked to other objects) style delegation
/**
* @desc OLOO(Objects linked to other objects) style delegation
* @see 《You Don't Know JS》 Chapter 6
*/
const Widget = {
width: 50,
height: 50,
// Constructor
init(width, height) {
this.width = width || this.width;
this.height = height || this.height;
this.$elem = null;
},
insert($where) {
if (this.$elem) {
this.$elem.css({
width: this.width + 'px',
height: this.height + 'px'
}).appendTo($where);
}
}
};
const createButton = function (mixins = []) {
// Delegation
let Button = Object.create(Widget);
let secretNum = 1;
Object.assign(Button, {
label: 'Default',
num: 0,
// Suggest different and more descriptive names
// to avoid the ugliness of the explicit pseudo-polymorphic calls.
setup(width, height, label) {
// Delegated call
this.init(width, height);
this.label = label || this.label;
this.$elem = $('<button>').text(this.label);
},
build($where) {
// Delegated call
this.insert($where);
this.$elem.click(this.onClick.bind(this));
},
onClick(event) {
console.log("Button '" + this.label + "' clicked!");
},
// Privileged function
getSecretNum() {
return secretNum;
}
// Concatenative
}, ...mixins);
return Button;
}
const canAnimate = {
animate() {
console.log('Animate!')
}
}
const Button = createButton();
const AnimatedButton = createButton([canAnimate]);
$(document).ready(function () {
let $body = $(document.body);
let btn1 = Object.create(Button);
btn1.setup(125, 30);
let btn2 = Object.create(AnimatedButton);
btn2.setup(150, 40, 'Animate');
btn1.build($body);
btn2.build($body);
btn2.animate();
console.log(btn1.num); // 0
console.log(btn1.secretNum); // undefined
console.log(btn1.getSecretNum()); // 1
console.log(Widget.isPrototypeOf(Button)); // true
console.log(Widget.isPrototypeOf(btn1)); // true
console.log(Button.isPrototypeOf(btn1)); // true
console.log(AnimatedButton.isPrototypeOf(btn2)); // true
console.log(Object.getPrototypeOf(btn1) === Widget); // false
console.log(Object.getPrototypeOf(btn1) === Button); // true
console.log(Object.getPrototypeOf(btn2) === AnimatedButton); // true
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment