Skip to content

Instantly share code, notes, and snippets.

@polotek
Created August 9, 2012 21:33
Show Gist options
  • Save polotek/3308233 to your computer and use it in GitHub Desktop.
Save polotek/3308233 to your computer and use it in GitHub Desktop.
A short explanation of prototypal inheritance.
function MyConstructor() {
this.foo = [ "foo" ];
}
MyConstructor.prototype.bar = [ "bar" ];
var obj = new MyConstructor();
obj.foo // The "foo" property is available directly on the object
obj.bar // The object has no "bar" property so it looks it up on the prototype
obj.bar === obj.__proto__.bar
obj.__proto__ === MyConstructor.prototype // This is the shared prototype of any objects created
// with this constructor
obj.__proto__.foo === undefined
var obj2 = new MyConstructor();
obj.foo !== obj2.foo // these are separate array instances created in the consturctor
obj.bar === obj2.bar // these are the exact same array looked up on the prototype
obj.__proto__ === obj2.__proto__ // these 2 objects share the exact same prototype
// Assume the system doesn't automatically lookup the prototype on an object.
// The lookup function for object properties might look like this.
function lookupProperty(obj, propertyName) {
// Skip the special prototype property
if(propertyName === '__proto__') { return obj.__proto__; }
// Check for the property on this actual instance
if(obj.hasOwnProperty(propertyName)) {
return obj[propertyName];
}
// If we didn't find it, we check the prototype if it's there
if(obj.__proto__) {
// Check for the property on the prototype object
if(obj.__proto__.hasOwnProperty(propertyName) {
return obj.__proto__[propertyName];
} else {
// Otherwise recurse up the chain with the prototype
return lookupProperty(obj.__proto__, propertyName);
}
}
return undefined;
}
// Keep in mind that the "__proto__" property is actually non-standard. The prototype of an object is
// supposed to be hidden. Normally you shouldn't be manipulating an object prototype directly. It's
// only accessed internally by the interpreter for things like property lookups. Most modern engines
// have exposed `__proto__` for various reasons and there is some debate about whether to standardize it.
@lesliepearson
Copy link

Overall, I think this does a great job of providing a simple explanation of prototypal inheritance.

A couple of these suggestions below are not necessarily that I didn't understand, but that may help provide clarity to total beginners.

  • Line 10: Maybe clarifying that The "bar" property is available on the object via the prototype b/c obj` does not have a "bar" property
  • Line 17 & 18 is super helpful, perhaps an example of pushing a string to obj.bar and then saying that if you were to console.log(obj2.bar), it would print out the same array b/c they're referencing the same thing. I understood what you were saying, but i went into the console and played around with it to make sure that this was pointing out that this was a reference thing to the prototype.
  • I'm not sure what you mean by line 22. Are you saying that this is your implementation of the lookupProperty fn and that this exists for all instantiated objects and when you call a property on the obj, something like this will happen?

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