Created
August 9, 2012 21:33
-
-
Save polotek/3308233 to your computer and use it in GitHub Desktop.
A short explanation of prototypal inheritance.
This file contains hidden or 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
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. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
The "bar" property is available on the object via the prototype b/c
obj` does not have a "bar" propertyobj.bar
and then saying that if you were toconsole.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.lookupProperty
fn and that this exists for all instantiated objects and when you call a property on the obj, something like this will happen?