JavaScript Prototyping Reference December, 2011
I've had problems remembering what is actually happening when working with constructor functions and prototyping. I created the following table to demonstrate what's going on. If I'm missing something please let me know as I'm not a JavaScript ninja by any means.
A couple of things to note:
- The __proto__ property is deprecated and non standard. I include it only as a way to indicate an object's prototype.
- I included the underscore.js extend function only to show how it compares to protypal inheritance in JS or CS. I think the name of this function is not clear.
- The backbone.js extend method is functionally equivalent to the CoffeeScript extends operator.
JavaScript | |
---|---|
var x = function() {} |
x = {
// Only meaningful for constructors not functions.
prototype: {
constructor: x,
__proto__: Object.prototype
},
__proto__: Function.prototype
}
|
var Y = function(name) { // In a constructor 'this' refers to the // new object. this.name = name; } Y.prototype.printName = function() { // In a method, 'this' refers to the // declaring object (Unless overridden). console.log(this.name); } var y = new Y('Fritz London'); |
Y = { // This will be set as the new objects prototype. prototype: { constructor: Y, __proto__: Object.prototype, printName: function() { console.log(this.name); } }, __proto__: Function.prototype } y = { __proto__: Y.prototype, name: 'Fritz London' } |
var z = { name: 'Richard Feynman' } |
z = {
__proto__: Object.prototype,
name: 'Richard Feynman'
}
|
var a = { name: 'Werner Heisenberg' } var createObject = function(prototype) { var F = function() {}; F.prototype = prototype; return new F(); } var b = createObject(a); // Or the built in var b = Object.create(a); |
a = {
__proto__: Object.prototype,
name: 'Werner Heisenberg'
}
F = {
prototype: a,
__proto__: Function.prototype
}
b = {
__proto__: a
}
|
CoffeeScript | |
class Parent constructor: -> @id = ++Parent.identity name: 'Niels Bohr' @identity: 0 |
function Parent() { this.id = ++Parent.identity; } Parent.prototype.name = 'Niels Bohr'; Parent.identity = 0; redirect_from: - /blog/2011/12/javascript-prototyping-reference.html --- Parent = { prototype: { constructor: Parent, __proto__: Object.prototype, name: 'Niels Bohr' }, __proto__: Function.prototype, identity: 0 } |
parent = new Parent()
|
parent = { __proto__: Parent.prototype, id: 1 } |
class Child extends Parent url: 'http://www.google.com' |
__extends(Child, Parent); function Child() { Child.__super__.constructor.apply(this, arguments); } Child.prototype.url = 'http://www.google.com'; redirect_from: - /blog/2011/12/javascript-prototyping-reference.html --- Child = { prototype: { constructor: Child, __proto__: Parent, url: 'http://www.google.com' }, __proto__: Function.prototype, // CoffeeScript generated property __super__: Parent.prototype } |
child = new Child()
|
child = { __proto__: Child.prototype, id: 1 } |
backbone.js | |
// [backbone.js].extend(protoProps, classProps) var Person = Backbone.Model.extend({ constructor: function() { this.id = ++Person.identity; }, name: 'Niels Bohr' }, { identity: 0 }); |
Person = { prototype: { // If a constructor property is not // specified, a new function is used // that calls the parent constructor // in the context of the new object. constructor: protoProps.constructor, __proto__: Backbone.Model.prototype, name: 'Niels Bohr' }, __proto__: Function.prototype, // Backbone added property __super__: Backbone.Model.prototype // Backbone attaches this to new objects extend: Backbone.Model.extend, identity: 0 } |
underscore.js | |
var person = { id: 5 } var a = { name: 'Werner Heisenberg' } var b = { occupation: 'Physicist' } _.extend(person, a, b); |
person = { id: 5, name: 'Werner Heisenberg', occupation: 'Physicist' } |