The "New" Keyword
In JavaScript
@batemanchris
Calling Functions With "NEW"
var myExample = new Example();
We Interrupt This Presentation on "New"
To Bring You A Presentation on Prototypes
pROTOTYPES
JS doesn't have classes, but it does have prototypal inheritance.
var simpleObject = {
a: 'a'
};
What does it look like?
{
a: 'a'
}
Then why can I do this?
simpleObject.toString(); // where the crap does this function come from?
Every object in JS has an "internal" property called prototype, which is basically a pointer to another object.
When you try to access a property (or function) on an object, JS tries to find it on the object first, and if it doesn't find it, it looks at the prototype.
var simpleObject = {
a: 'a'
};
Reality
{
a: 'a',
__proto__: {
...
toString: function,
hasOwnProperty: function,
...
}
}
Note: Accessing the prototype with __proto__ is part of ES6
though you probably don't want to do it in real code - use Object.getPrototypeOf() instead
Function Prototypes
var Demo = function() {
...
};
Demo.prototype.doSomething = function() {
...
};
When you create a new function, it will have a .prototype property that contains an empty object.
You can add to it, or replace it completely.
This prototype property is not the same as __proto__.
Back to "new"
Here's a function:
var Demo = function() {
this.prop = 'text';
};
Demo.prototype.action = function() {
alert(this.prop);
};
Lets go ahead and call it:
var myDemo = Demo();
myDemo; // undefined
myDemo.action() // ERROR
window.prop; // 'text'
Crap.
Take 2
Ok, let's try calling our function:
var Demo = function() {
this.prop = 'text';
};
Demo.prototype.action = function() {
alert(this.prop);
};
With "new"
var myDemo = new Demo();
myDemo; // { prop:'a', action:function }
window.prop; // undefined
myDemo.action(); // alerts "text"
What Does "new" do?
var Demo = function() {
this.prop = 'text';
};
Demo.prototype.action = function() {
alert(this.prop);
};
var myDemo = new Demo();
- A new, empty object is created: { }
- That object's prototype ( __proto__ )
is set to Demo.prototype - The Demo function is executed - using the
new, empty object as "this" - The new object is returned
What Does "New" Do?
var Demo = function() {
this.prop = 'text';
};
Demo.prototype.action = function() {
alert(this.prop);
};
var myDemo = new Demo();
the new call is equivalent to this:
var myDemo = { };
myDemo.__proto__ = Demo.prototype;
Demo.call(myDemo);
Arguments Against "New"
- Makes it look like JS does classical inheritance
- instanceof and .constructor can have odd behavior
- Implementors might forget to use "new"
- Crockford doesn't like it
More Reading
Object.Create
Object.create(myProtoObject);
Creates a new, empty object – with its __proto__ set to myProtoObject.Want to create a pure object, that doensn't inherit from any prototype?
var obj = Object.create(null); // returns { }
obj.toString(); // ERROR
Object.create
var Demo = function() {
this.prop = 'text';
};
Demo.prototype.action = function() {
alert(this.prop);
};
var myDemo = new Demo();
var Demo = {
init: function() {
this.prop = 'text';
},
action: function() {
alert(this.prop);
}
};
var myDemo = Object.create(Demo);
myDemo.init();
Summary
var myDemo = new Demo();
=
var myDemo = Object.create(Demo.prototype);
Demo.call(myDemo);
=
var myDemo = { };
myDemo.__proto__ = Demo.prototype;
Demo.call(myDemo);
Questions?
The "New" Keyword in JavaScript
By Chris Bateman
The "New" Keyword in JavaScript
- 1,690