Created
January 18, 2015 19:30
-
-
Save awilson28/e83ed50b56d5fd6f7481 to your computer and use it in GitHub Desktop.
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
1. To your first question regarding the difference between JavaScript and class-based languages like Java: | |
Constructor functions in JS do in fact provide the same functionality that classes provide to Java. The difference lies in the extent to which Java fundamentally depends on classes. For instance, in Java, every object is an instance of a specific class. An object literally cannot be created if the class for it doesn’t exist. In JavaScript, unlike in Java, we can create an object super easily: | |
var newObject = {}; | |
newObject.__proto__ // Object {} | |
Try this out in your console. This simple object declaration prompts the JavaScript engine to set newObject’s __proto__ property to Object. This happens behind the scenes. This __proto__ property enables newObject to enjoy the prototype methods defined for all Objects. You can check out these built in methods here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object | |
So, what’s happening behind the scenes to execute inheritance in JS is different from what drives inheritance in Java. However, for the most part, function constructors in JS can perform in the same ways that classes do in Java. | |
2. To your second point regarding the difference between __proto__ and prototype: | |
In fact, __proto__, which is set at object creation, is the actual object that the JavaScript engine uses to look up the prototype chain and prototype is the object that is used to construct __proto__. | |
The prototype property is only available to functions. Function Constructors have their own [[prototype]] chain that is completely separate from the [[prototype]] chains of the objects they initialize. Again: Prototype is a property that belongs to functions and __proto__ is a property that all objects have including constructor functions. | |
So, in JavaScript: | |
1. function Car () {} | |
2. Car.__proto__ === Function.prototype //true | |
3. Function.prototype.__proto__ === Object.prototype // true | |
4. Object.prototype.__proto__ === null //true | |
Every Car inherits from Function.prototype which inherits from Object.prototype, and Object.prototype’s internal prototype is null, which informs JS’s inheritance algorithm when it has reached the end of the chain. | |
So, regarding this updated gist on __proto__ , | |
(new Parent).__proto__ === Parent.prototype // logs true | |
(new Parent).prototype === undefined // logs true | |
(new Parent).constructor.prototype === Parent.prototype // logs true | |
You are right, Vincent, when you say that we can set __proto_: | |
function Shelter () {} | |
var cabin = new Shelter() | |
cabin.__proto__ // Shelter {} | |
function Residence () {} | |
cabin.__proto__ = Residence.prototype | |
cabin.__proto__ // Residence {} | |
You can also check out the gist. | |
It is important to keep in mind, though, that __proto__ was created to be inaccessible. Though it is in fact accessible, we should act as if it isn’t accessible. | |
From the Mozilla Developer Network: | |
“The __proto__ property of Object.prototype is an accessor property (a getter function and a setter function) that exposes the internal [[Prototype]] (either an object or null) of the object through which it is accessed. | |
The use of __proto__ is controversial, and has been discouraged by many. It was never originally included in the EcmaScript language spec, but modern browsers decided to implement it anyway. Today, the __proto__ property has been standardized in the ECMAScript 6 language specification and will be supported into the future. Still, mutating the [[Prototype]] of an object is a slow operation that should be avoided if performance is a concern. | |
The __proto__ property can also be used in an object literal definition to set the object [[Prototype]] on creation, as an alternative to Object.create. See: object initializer / literal syntax.” | |
Please refer to this stack overflow discussion for helpful diagrams of __proto__: | |
http://stackoverflow.com/questions/9959727/proto-vs-prototype-in-javascript | |
3. Regarding the functional difference between classical and prototypal inheritance: | |
The distinction is mostly philosophical. Classical and prototypal inheritance provide the same functionality. Many JS developers prefer prototypal inheritance (as mentioned in the review, prototypal inheritance is built into JS with Object.create()) but the debate is still ongoing as to which method is ‘better’. | |
Refer to this stack overflow discussion: | |
http://stackoverflow.com/questions/2800964/benefits-of-prototypal-inheritance-over-classical | |
And check out Principles of Object Oriented JavaScript by Zakas to learn more. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment