Skip to content

Instantly share code, notes, and snippets.

@getify
Last active January 7, 2024 11:58
Show Gist options
  • Save getify/5572383 to your computer and use it in GitHub Desktop.
Save getify/5572383 to your computer and use it in GitHub Desktop.
OLOO (objects linked to other objects) pattern explored (with comparison to the prototype style of the same code)
function Foo(who) {
this.me = who;
}
Foo.prototype.identify = function() {
return "I am " + this.me;
};
function Bar(who) {
Foo.call(this,"Bar:" + who);
}
Bar.prototype = Object.create(Foo.prototype);
Bar.prototype.constructor = Bar; // "fixes" the delegated `constructor` reference
Bar.prototype.speak = function() {
alert("Hello, " + this.identify() + ".");
};
var b1 = new Bar("b1");
var b2 = new Bar("b2");
b1.speak(); // alerts: "Hello, I am Bar:b1."
b2.speak(); // alerts: "Hello, I am Bar:b2."
// some type introspection
b1 instanceof Bar; // true
b2 instanceof Bar; // true
b1 instanceof Foo; // true
b2 instanceof Foo; // true
Bar.prototype instanceof Foo; // true
Bar.prototype.isPrototypeOf(b1); // true
Bar.prototype.isPrototypeOf(b2); // true
Foo.prototype.isPrototypeOf(b1); // true
Foo.prototype.isPrototypeOf(b2); // true
Foo.prototype.isPrototypeOf(Bar.prototype); // true
Object.getPrototypeOf(b1) === Bar.prototype; // true
Object.getPrototypeOf(b2) === Bar.prototype; // true
Object.getPrototypeOf(Bar.prototype) === Foo.prototype; // true
var Foo = {
Foo: function(who) {
this.me = who;
return this;
},
identify: function() {
return "I am " + this.me;
}
};
var Bar = Object.create(Foo);
Bar.Bar = function(who) {
// "constructors" (aka "initializers") are now in the `[[Prototype]]` chain,
// so `this.Foo(..)` works easily w/o any problems of relative-polymorphism
// or .call(this,..) awkwardness of the implicit "mixin" pattern
this.Foo("Bar:" + who);
return this;
};
Bar.speak = function() {
alert("Hello, " + this.identify() + ".");
};
var b1 = Object.create(Bar).Bar("b1");
var b2 = Object.create(Bar).Bar("b2");
b1.speak(); // alerts: "Hello, I am Bar:b1."
b2.speak(); // alerts: "Hello, I am Bar:b2."
// some type introspection
Bar.isPrototypeOf(b1); // true
Bar.isPrototypeOf(b2); // true
Foo.isPrototypeOf(b1); // true
Foo.isPrototypeOf(b2); // true
Foo.isPrototypeOf(Bar); // true
Object.getPrototypeOf(b1) === Bar; // true
Object.getPrototypeOf(b2) === Bar; // true
Object.getPrototypeOf(Bar) === Foo; // true
@blachawk
Copy link

blachawk commented Mar 1, 2018

I believe through this practice the key takeaway is Behavior Delegation of objects linking to other objects.

@BenceSzalai
Copy link

OLOO for the win. Also add this to Foo:

  [Symbol.hasInstance](instance) {
    return this.isPrototypeOf(instance)
  }

so this will work fine too:

b1 instanceof Bar; // true
b2 instanceof Bar; // true
b1 instanceof Foo; // true
b2 instanceof Foo; // true

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment