Can someone please explain Douglas Crockford's uber method? - javascript

I went through the following example from here
But I am not able to understand from LINE 1:
Function.method('inherits', function(parent){
this.prototype = new parent();
var d = {},
p = this.prototype;
this.prototype.constructor = parent;
this.method('uber', function uber(name){ //LINE 1
if(!(name in d)){
d[name] = 0;
}
var f, r, t = d[name], v = parent.prototype;
if(t){
while(t){
v = v.constructor.prototype;
t -= 1;
}
f = v[name];
} else {
f = p[name];
if(f == this[name]){
f = v[name];
}
}
d[name] +=1;
r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
d[name] -= 1;
return r;
});
return this;
});

I went through the following example of Douglas Crockford's uber method
Oh, you poor lost soul. Notice that this function had its origin in 2002 (or earlier), when the language standard version was still ES3. This year, we will see ES9!
You can check the web archive to see the function slowly evolving to deal with all the edge cases that were discovered, and Crockford trying to fix them. (Notice that it still fails horribly if one of the involved methods throws an exception).
Needless to say, this is totally outdated. And borked.
Can someone please explain it?
I'll try to take a shot. Lets take the following code:
function A() { }
A.prototype.exampleMethod = function() {
console.log("top");
return "result";
};
function B() { }
B.inherits(A);
B.prototype.exampleMethod = function() {
console.log("parent");
return this.uber("exampleMethod");
};
function C() {
this.exampleMethod = function() {
console.log("instance");
return this.uber("exampleMethod");
}
}
C.inherits(B);
C.prototype.exampleMethod = function() {
console.log("prototype");
return this.uber("exampleMethod");
};
var x = new C();
console.log(x.exampleMethod());
This does should log instance, prototype, parent, top, result - as one might have expected from a "super" call. How do these this.uber("exampleMethod") invocations - the same method called with the same arguments on the same instance - achieve this? Horrible jugglery and trickery.
We see that this.uber always calls the method that C.inherits(B) had created. B.prototype.uber is irrelevant. All calls will use the same d object (referenced by closure), which stores the recursion depth per method name. p is C.prototype, and v is B.prototype.
The first call is from the instance method (created in the constructor). d.exampleMethod is still 0 (or was just initialised to it as it didn't exist before), and we go to the else branch to select the next method to call. Here it checks p[name] == this[name], i.e. C.prototype.exampleMethod == x.exampleMethod, which is false when the instance (this/x) has an own (instance) method. So it selects the method from p, not from v, to call next. It increments the recursion count and calls it on the instance.
The second call is from the C.prototype method. If this was the first call (as usual when having only prototype methods), d.exampleMethod would be 0. Again we'd go to the else branch, but when there is no instance method we would have the comparison evaluate to true and would select v[name] to call, i.e. the parent method we inherited. It would increment the recursion count and call the selected method.
The third call would be from the B.prototype method, and d.exampleMethod would be 1. This actually already happens in the second call, because Crockford forgot to account for the instance method here. Anyway, it now goes to the if branch and goes up the prototype chain from v, assuming that the .constructor property is properly set up everywhere (inherits did it). It does so the for the stored number of times, and then selects the next method to call from the respective object - A.prototype.exampleMethod in our case.
The counting must be per-methodname, as one could attempt to call a different method from any of the invoked super methods.
At least that must have been the idea, as obviously the counting is totally off in case there is an instance method. Or when there are objects in there prototype chain that don't own the respective method - maybe also that was a case that Crockford attempted but failed to deal with.

If you're trying to understand how classes could be implemented using ES5 and how to implement inheritance of classes, the code example from Douglas Crockford is kinda outdated and just a pure mess.
This makes it extremly difficult for beginners to understand it. (Also his explanation lacks a fair amount of detail and is not helping at all)
In my opinion a much better example of how to implement a class pattern with ES5 would be: http://arjanvandergaag.nl/blog/javascript-class-pattern.html
But netherless, lets go trough it step by step:
// He extended the "prototype" of the Function object to have some syntactic sugar
// for extending prototypes with new methods (a method called 'method').
// This line extends the prototype of the Function object by a method called 'inherits' using the syntactic sugar method mentioned above.
Function.method('inherits', function(parent){
/** 'this' is a reference to the Function the 'inherits' method is called
* on, for example lets asume you defined a function called 'Apple'
* and call the method 'inherits' on it, 'this' would be a reference of 'Apple'-Function object.
**/
/**
* Hes extending the prototype of the base function by the prototype of
* the 'parent' function (the only argument the 'inherits' method takes),
* by creating a new instance of it.
**/
this.prototype = new parent();
// BAD VARIABLE NAMING!!!
var d = {}, // variable to create a dictionary for faster lookup later on.
p = this.prototype; // save the prototype of the base function into variable with a short name
this.prototype.constructor = parent; // set the constructor of the base function to be the parent.
/**
* Extend the base function's prototype by a method called 'uber',
* it will nearly the same function as the 'super' keyword in OO-languages,
* but only to call methods of the parent class.
**/
this.method('uber', function uber(name){
if(!(name in d)){
// if the value name doesn't exist in the dictionary
d[name] = 0; // set the key to the value of name and the value to 0
}
// BAD VARIABLE NAMING AGAIN!!!
var f, r, t = d[name], v = parent.prototype;
// f is used to store the method to call later on.
// t is the value of the key inside the 'd' dictionary which indicates the depth to go up the prototype tree
// v is the parent functions prototype
// r is the result the method 'f' yields later on.
// check if the attribute 'name' exists in the dicionary.
// because if it doesn't exist t will be 0 which resolves to false.
if(t){
// the loop is used to walk the tree prototype tree until the implementation with the depth of t is found.
while(t){
v = v.constructor.prototype;
t -= 1;
}
f = v[name]; // set f to the method name of the t-th parent protoype
} else {
// if the attibute 'name' doesn't exist inside the dictionary
f = p[name]; // use the method 'name' of the base class prototype.
if(f == this[name]){
// if the method 'name' is a member of the base class
f = v[name]; // use the method 'name' of the parent prototype instead.
}
}
// increment the corresponding dictionary value for the depth of the 'uber' call.
d[name] +=1;
// call the method saved to 'f' in context of the base class and apply the 'arguments' array to it and save the result to 'r'.
r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
// decrement the corresponding dictionary value for the depth of the 'uber' call.
d[name] -= 1;
// return the result
return r;
});
return this;
});
Hope this explanation kinda helps you, but i might be wrong on some lines because the code is such a weird implementation and is far off from easily readable.

Related

Difference between function defined inside object constructor versus on the prototype [duplicate]

What's the difference between
var A = function () {
this.x = function () {
//do something
};
};
and
var A = function () { };
A.prototype.x = function () {
//do something
};
The examples have very different outcomes.
Before looking at the differences, the following should be noted:
A constructor's prototype provides a way to share methods and values among instances via the instance's private [[Prototype]] property.
A function's this is set by how the function is called or by the use of bind (not discussed here). Where a function is called on an object (e.g. myObj.method()) then this within the method references the object. Where this is not set by the call or by the use of bind, it defaults to the global object (window in a browser) or in strict mode, remains undefined.
JavaScript is an object-oriented language, i.e. most values are objects, including functions. (Strings, numbers, and booleans are not objects.)
So here are the snippets in question:
var A = function () {
this.x = function () {
//do something
};
};
In this case, variable A is assigned a value that is a reference to a function. When that function is called using A(), the function's this isn't set by the call so it defaults to the global object and the expression this.x is effective window.x. The result is that a reference to the function expression on the right-hand side is assigned to window.x.
In the case of:
var A = function () { };
A.prototype.x = function () {
//do something
};
something very different occurs. In the first line, variable A is assigned a reference to a function. In JavaScript, all functions objects have a prototype property by default so there is no separate code to create an A.prototype object.
In the second line, A.prototype.x is assigned a reference to a function. This will create an x property if it doesn't exist, or assign a new value if it does. So the difference with the first example in which object's x property is involved in the expression.
Another example is below. It's similar to the first one (and maybe what you meant to ask about):
var A = new function () {
this.x = function () {
//do something
};
};
In this example, the new operator has been added before the function expression so that the function is called as a constructor. When called with new, the function's this is set to reference a new Object whose private [[Prototype]] property is set to reference the constructor's public prototype. So in the assignment statement, the x property will be created on this new object. When called as a constructor, a function returns its this object by default, so there is no need for a separate return this; statement.
To check that A has an x property:
console.log(A.x) // function () {
// //do something
// };
This is an uncommon use of new since the only way to reference the constructor is via A.constructor. It would be much more common to do:
var A = function () {
this.x = function () {
//do something
};
};
var a = new A();
Another way of achieving a similar result is to use an immediately invoked function expression:
var A = (function () {
this.x = function () {
//do something
};
}());
In this case, A assigned the return value of calling the function on the right-hand side. Here again, since this is not set in the call, it will reference the global object and this.x is effective window.x. Since the function doesn't return anything, A will have a value of undefined.
These differences between the two approaches also manifest if you're serializing and de-serializing your Javascript objects to/from JSON. Methods defined on an object's prototype are not serialized when you serialize the object, which can be convenient when for example you want to serialize just the data portions of an object, but not it's methods:
var A = function () {
this.objectsOwnProperties = "are serialized";
};
A.prototype.prototypeProperties = "are NOT serialized";
var instance = new A();
console.log(instance.prototypeProperties); // "are NOT serialized"
console.log(JSON.stringify(instance));
// {"objectsOwnProperties":"are serialized"}
Related questions:
What does it mean that JavaScript is a prototypal language?
What is the scope of a function in JavaScript?
How does the "this" keyword work?
Sidenote: There may not be any significant memory savings between the two approaches, however using the prototype to share methods and properties will likely use less memory than each instance having its own copy.
JavaScript isn't a low-level language. It may not be very valuable to think of prototyping or other inheritance patterns as a way to explicitly change the way memory is allocated.
As others have said the first version, using "this" results in every instance of the class A having its own independent copy of function method "x". Whereas using "prototype" will mean that each instance of class A will use the same copy of method "x".
Here is some code to show this subtle difference:
// x is a method assigned to the object using "this"
var A = function () {
this.x = function () { alert('A'); };
};
A.prototype.updateX = function( value ) {
this.x = function() { alert( value ); }
};
var a1 = new A();
var a2 = new A();
a1.x(); // Displays 'A'
a2.x(); // Also displays 'A'
a1.updateX('Z');
a1.x(); // Displays 'Z'
a2.x(); // Still displays 'A'
// Here x is a method assigned to the object using "prototype"
var B = function () { };
B.prototype.x = function () { alert('B'); };
B.prototype.updateX = function( value ) {
B.prototype.x = function() { alert( value ); }
}
var b1 = new B();
var b2 = new B();
b1.x(); // Displays 'B'
b2.x(); // Also displays 'B'
b1.updateX('Y');
b1.x(); // Displays 'Y'
b2.x(); // Also displays 'Y' because by using prototype we have changed it for all instances
As others have mentioned, there are various reasons to choose one method or the other. My sample is just meant to clearly demonstrate the difference.
Take these 2 examples:
var A = function() { this.hey = function() { alert('from A') } };
vs.
var A = function() {}
A.prototype.hey = function() { alert('from prototype') };
Most people here (especially the top-rated answers) tried to explain how they are different without explaining WHY. I think this is wrong and if you understand the fundamentals first, the difference will become obvious. Let's try to explain the fundamentals first...
a) A function is an object in JavaScript. EVERY object in JavaScript gets an internal property (meaning, you can't access it like other properties, except maybe in browsers like Chrome), often referred to as __proto__ (you can actually type anyObject.__proto__ in Chrome to see what it references. This is just that, a property, nothing more. A property in JavaScript = a variable inside an object, nothing more. What do variables do? They point to things.
So what does this __proto__ property points to? Well, usually another object (we'll explain why later). The only way to force JavaScript for the __proto__ property to NOT point to another object is to use var newObj = Object.create(null). Even if you do this, the __proto__ property STILL exists as a property of the object, just it doesn't point to another object, it points to null.
Here's where most people get confused:
When you create a new function in JavaScript (which is an object as well, remember?), the moment it is defined, JavaScript automatically creates a new property on that function called prototype. Try it:
var A = [];
A.prototype // undefined
A = function() {}
A.prototype // {} // got created when function() {} was defined
A.prototype is TOTALLY DIFFERENT from the __proto__ property. In our example, 'A' now has TWO properties called 'prototype' and __proto__ . This is a big confusion for people. prototype and __proto__ properties are in no way related, they're separate things pointing to separate values.
You may wonder: Why does JavaScript has __proto__ property created on every single object? Well, one word: delegation. When you call a property on an object and the object doesn't have it, then JavaScript looks for the object referenced by __proto__ to see if it maybe has it. If it doesn't have it, then it looks at that object's __proto__ property and so on...until the chain ends. Thus the name prototype chain. Of course, if __proto__ doesn't point to an object and instead points to null, well tough luck, JavaScript realizes that and will return you undefined for the property.
You may also wonder, why does JavaScript creates a property called prototype for a function when you define the function? Because it tries to fool you, yes fool you that it works like class-based languages.
Let's go on with our example and create an "object" out of A:
var a1 = new A();
There's something happening in the background when this thing happened. a1 is an ordinary variable which was assigned a new, empty object.
The fact that you used the operator new before a function invocation A() did something ADDITIONAL in the background. The new keyword created a new object which now references a1 and that object is empty. Here's what happening additionally:
We said that on each function definition there's a new property created called prototype (which you can access it, unlike with the __proto__ property) created? Well, that property is being used now.
So we're now at the point where we have a freshly baked empty a1 object. We said that all objects in JavaScript have an internal __proto__ property which points to something (a1 also has it), whether it's null or another object. What the new operator does is that it sets that __proto__ property to point to the function's prototype property. Read that again. It's basically this:
a1.__proto__ = A.prototype;
We said that A.prototype is nothing more than an empty object (unless we change it to something else before defining a1). So now basically a1.__proto__ points to the same thing A.prototype points to, which is that empty object. They both point to the same object which was created when this line happened:
A = function() {} // JS: cool. let's also create A.prototype pointing to empty {}
Now, there's another thing happening when var a1 = new A() statement is processed. Basically A() is executed and if A is something like this:
var A = function() { this.hey = function() { alert('from A') } };
All that stuff inside function() { } is going to execute. When you reach the this.hey.. line, this is changed to a1 and you get this:
a1.hey = function() { alert('from A') }
I won't cover why this changes to a1 but this is a great answer to learn more.
So to summarize, when you do var a1 = new A() there are 3 things happening in the background:
A totally new empty object is created and assigned to a1. a1 = {}
a1.__proto__ property is assigned to point at the same thing as A.prototype points to (another empty object {} )
The function A() is being executed with this set to the new, empty object created in step 1 (read the answer I referenced above as to why this changes to a1)
Now, let's try to create another object:
var a2 = new A();
Steps 1,2,3 will repeat. Do you notice something? The key word is repeat. Step 1: a2 will be a new empty object, step 2: its __proto__ property will point to the same thing A.prototype points to and most importantly, step 3: function A() is AGAIN executed, which means that a2 will get hey property containing a function. a1 and a2 have two SEPARATE properties named hey which point to 2 SEPARATE functions! We now have duplicate functions in same two different objects doing the same thing, oops...You can imagine the memory implications of this if we have 1000 objects created with new A, after all functions declarations take more memory than something like the number 2. So how do we prevent this?
Remember why the __proto__ property exists on every object? So that if you retrieve the yoMan property on a1 (which doesn't exist), its __proto__ property will be consulted, which if it's an object (and is most cases it is), it will check if it contains yoMan, and if it doesn't, it will consult that object's __proto__ etc. If it does, it will take that property value and display it to you.
So someone decided to use this fact + the fact that when you create a1, its __proto__ property points to the same (empty) object A.prototype points to and do this:
var A = function() {}
A.prototype.hey = function() { alert('from prototype') };
Cool! Now, when you create a1, it again goes through all of the 3 steps above, and in step 3, it doesn't do anything, since function A() has nothing to execute. And if we do:
a1.hey
It will see that a1 does not contain hey and it will check its __proto__ property object to see if it has it, which is the case.
With this approach we eliminate the part from step 3 where functions are duplicated on each new object creation. Instead of a1 and a2 having a separate hey property, now NONE of them has it. Which, I guess, you figured out yourself by now. That's the nice thing...if you understand __proto__ and Function.prototype, questions like these will be pretty obvious.
NOTE: Some people tend to not call the internal Prototype property as __proto__, I've used this name through the post to distinguish it clearly to the Functional.prototype property as two different things.
In most cases they are essentially the same, but the second version saves memory because there is only one instance of the function instead of a separate function for each object.
A reason to use the first form is to access "private members". For example:
var A = function () {
var private_var = ...;
this.x = function () {
return private_var;
};
this.setX = function (new_x) {
private_var = new_x;
};
};
Because of javascript's scoping rules, private_var is available to the function assigned to this.x, but not outside the object.
The first example changes the interface for that object only. The second example changes the interface for all object of that class.
The ultimate problem with using this instead of prototype is that when overriding a method, the constructor of the base class will still refer to the overridden method. Consider this:
BaseClass = function() {
var text = null;
this.setText = function(value) {
text = value + " BaseClass!";
};
this.getText = function() {
return text;
};
this.setText("Hello"); // This always calls BaseClass.setText()
};
SubClass = function() {
// setText is not overridden yet,
// so the constructor calls the superclass' method
BaseClass.call(this);
// Keeping a reference to the superclass' method
var super_setText = this.setText;
// Overriding
this.setText = function(value) {
super_setText.call(this, "SubClass says: " + value);
};
};
SubClass.prototype = new BaseClass();
var subClass = new SubClass();
console.log(subClass.getText()); // Hello BaseClass!
subClass.setText("Hello"); // setText is already overridden
console.log(subClass.getText()); // SubClass says: Hello BaseClass!
versus:
BaseClass = function() {
this.setText("Hello"); // This calls the overridden method
};
BaseClass.prototype.setText = function(value) {
this.text = value + " BaseClass!";
};
BaseClass.prototype.getText = function() {
return this.text;
};
SubClass = function() {
// setText is already overridden, so this works as expected
BaseClass.call(this);
};
SubClass.prototype = new BaseClass();
SubClass.prototype.setText = function(value) {
BaseClass.prototype.setText.call(this, "SubClass says: " + value);
};
var subClass = new SubClass();
console.log(subClass.getText()); // SubClass says: Hello BaseClass!
If you think this is not a problem, then it depends on whether you can live without private variables, and whether you are experienced enough to know a leak when you see one. Also, having to put the constructor logic after the method definitions is inconvenient.
var A = function (param1) {
var privateVar = null; // Private variable
// Calling this.setPrivateVar(param1) here would be an error
this.setPrivateVar = function (value) {
privateVar = value;
console.log("setPrivateVar value set to: " + value);
// param1 is still here, possible memory leak
console.log("setPrivateVar has param1: " + param1);
};
// The constructor logic starts here possibly after
// many lines of code that define methods
this.setPrivateVar(param1); // This is valid
};
var a = new A(0);
// setPrivateVar value set to: 0
// setPrivateVar has param1: 0
a.setPrivateVar(1);
//setPrivateVar value set to: 1
//setPrivateVar has param1: 0
versus:
var A = function (param1) {
this.setPublicVar(param1); // This is valid
};
A.prototype.setPublicVar = function (value) {
this.publicVar = value; // No private variable
};
var a = new A(0);
a.setPublicVar(1);
console.log(a.publicVar); // 1
Every object is linked to a prototype object. When trying to access a property that does not exist, JavaScript will look in the object's prototype object for that property and return it if it exists.
The prototype property of a function constructor refers to the prototype object of all instances created with that function when using new.
In your first example, you are adding a property x to each instance created with the A function.
var A = function () {
this.x = function () {
//do something
};
};
var a = new A(); // constructor function gets executed
// newly created object gets an 'x' property
// which is a function
a.x(); // and can be called like this
In the second example you are adding a property to the prototype object that all the instances created with A point to.
var A = function () { };
A.prototype.x = function () {
//do something
};
var a = new A(); // constructor function gets executed
// which does nothing in this example
a.x(); // you are trying to access the 'x' property of an instance of 'A'
// which does not exist
// so JavaScript looks for that property in the prototype object
// that was defined using the 'prototype' property of the constructor
In conclusion, in the first example a copy of the function is assigned to each instance. In the second example a single copy of the function is shared by all instances.
What's the difference? => A lot.
I think, the this version is used to enable encapsulation, i.e. data hiding.
It helps to manipulate private variables.
Let us look at the following example:
var AdultPerson = function() {
var age;
this.setAge = function(val) {
// some housekeeping
age = val >= 18 && val;
};
this.getAge = function() {
return age;
};
this.isValid = function() {
return !!age;
};
};
Now, the prototype structure can be applied as following:
Different adults have different ages, but all of the adults get the same rights.
So, we add it using prototype, rather than this.
AdultPerson.prototype.getRights = function() {
// Should be valid
return this.isValid() && ['Booze', 'Drive'];
};
Lets look at the implementation now.
var p1 = new AdultPerson;
p1.setAge(12); // ( age = false )
console.log(p1.getRights()); // false ( Kid alert! )
p1.setAge(19); // ( age = 19 )
console.log(p1.getRights()); // ['Booze', 'Drive'] ( Welcome AdultPerson )
var p2 = new AdultPerson;
p2.setAge(45);
console.log(p2.getRights()); // The same getRights() method, *** not a new copy of it ***
Hope this helps.
I know this has been answered to death but I'd like to show an actual example of speed differences.
Function directly on object:
function ExampleFn() {
this.print = function() {
console.log("Calling print! ");
}
}
var objects = [];
console.time('x');
for (let i = 0; i < 2000000; i++) {
objects.push(new ExampleFn());
}
console.timeEnd('x');
//x: 1151.960693359375ms
Function on prototype:
function ExampleFn() {
}
ExampleFn.prototype.print = function() {
console.log("Calling print!");
}
var objects = [];
console.time('y');
for (let i = 0; i < 2000000; i++) {
objects.push(new ExampleFn());
}
console.timeEnd('y');
//x: 617.866943359375ms
Here we're creating 2,000,000 new objects with a print method in Chrome. We're storing every object in an array. Putting print on the prototype takes about 1/2 as long.
Prototype is the template of the class; which applies to all future instances of it. Whereas this is the particular instance of the object.
Let me give you a more comprehensive answer that I learned during a JavaScript training course.
Most answers mentioned the difference already, i.e. when prototyping the function is shared with all (future) instances. Whereas declaring the function in the class will create a copy for each instance.
In general there is no right or wrong, it's more a matter of taste or a design decision depending on your requirements. The prototype however is the technique that is used to develop in an object oriented manner, as I hope you'll see at the end of this answer.
You showed two patterns in your question. I will try to explain two more and try to explain the differences if relevant. Feel free to edit/extend.
In all examples it is about a car object that has a location and can move.
Object Decorator pattern
Not sure if this pattern is still relevant nowadays, but it exists. And it is good to know about it.
You simply pass an object and a property to the decorator function. The decorator returns the object with property and method.
var carlike = function(obj, loc) {
obj.loc = loc;
obj.move = function() {
obj.loc++;
};
return obj;
};
var amy = carlike({}, 1);
amy.move();
var ben = carlike({}, 9);
ben.move();
Functional Classes
A function in JavaScript is a specialised object. In addition to being invoked, a function can store properties like any other object.
In this case Car is a function (also think object) that can be invoked as you are used to do. It has a property methods (which is an object with a move function). When Car is invoked the extend function is called, which does some magic, and extends the Car function (think object) with the methods defined within methods.
This example, though different, comes closest to the first example in the question.
var Car = function(loc) {
var obj = {loc: loc};
extend(obj, Car.methods);
return obj;
};
Car.methods = {
move : function() {
this.loc++;
}
};
var amy = Car(1);
amy.move();
var ben = Car(9);
ben.move();
Prototypal Classes
The first two patterns allow a discussion of using techniques to define shared methods or using methods that are defined inline in the body of the constructor. In both cases every instance has its own move function.
The prototypal pattern does not lend itself well to the same examination, because function sharing via a prototype delegation is the very goal for the prototypal pattern. As others pointed out, it is expected to have a better memory footprint.
However there is one point interesting to know:
Every prototype object has has a convenience property constructor, which points back to the function (think object) it came attached to.
Concerning the last three lines:
In this example Car links to the prototype object, which links via constructor to Car itself, i.e. Car.prototype.constructor is Car itself. This allows you to figure out which constructor function built a certain object.
amy.constructor's lookup fails and thus is delegated to Car.prototype, which does have the constructor property. And so amy.constructor is Car.
Furthermore, amy is an instanceof Car. The instanceof operator works by seeing if the right operand's prototype object (Car) can be found anywhere in the left operand's prototype (amy) chain.
var Car = function(loc) {
var obj = Object.create(Car.prototype);
obj.loc = loc;
return obj;
};
Car.prototype.move = function() {
this.loc++;
};
var amy = Car(1);
amy.move();
var ben = Car(9);
ben.move();
console.log(Car.prototype.constructor);
console.log(amy.constructor);
console.log(amy instanceof Car);
Some developers can be confused in the beginning. See below example:
var Dog = function() {
return {legs: 4, bark: alert};
};
var fido = Dog();
console.log(fido instanceof Dog);
The instanceof operator returns false, because Dog's prototype cannot be found anywhere in fido's prototype chain. fido is a simple object that is created with an object literal, i.e. it just delegates to Object.prototype.
Pseudoclassical patterns
This is really just another form of the prototypal pattern in simplified form and more familiar to do those who program in Java for example, since it uses the new constructor.
It does the same as in the prototypal pattern really, it is just syntactic sugar overtop of the prototypal pattern.
However, the primary difference is that there are optimizations implemented in JavaScript engines that only apply when using the pseudoclassical pattern. Think of the pseudoclassical pattern a probably faster version of the prototypal pattern; the object relations in both examples are the same.
var Car = function(loc) {
this.loc = loc;
};
Car.prototype.move = function() {
this.loc++;
};
var amy = new Car(1);
amy.move();
var ben = new Car(9);
ben.move();
Finally, it should not be too difficult to realize how object oriented programming can be done. There are two sections.
One section that defines common properties/methods in the prototype (chain).
And another section where you put the definitions that distinguish the objects from each other (loc variable in the examples).
This is what allows us to apply concepts like superclass or subclass in JavaScript.
Feel free to add or edit. Once more complete I could make this a community wiki maybe.
I believe that #Matthew Crumley is right. They are functionally, if not structurally, equivalent. If you use Firebug to look at the objects that are created using new, you can see that they are the same. However, my preference would be the following. I'm guessing that it just seems more like what I'm used to in C#/Java. That is, define the class, define the fields, constructor, and methods.
var A = function() {};
A.prototype = {
_instance_var: 0,
initialize: function(v) { this._instance_var = v; },
x: function() { alert(this._instance_var); }
};
EDIT Didn't mean to imply that the scope of the variable was private, I was just trying to illustrate how I define my classes in javascript. Variable name has been changed to reflect this.
As discussed in other answers, it's really a performance consideration because the function in the prototype is shared with all of the instantiations - rather than the function being created for each instantiation.
I put together a jsperf to show this. There is a dramatic difference in the time it takes to instantiate the class, although it is really only relevant if you are making many instances.
http://jsperf.com/functions-in-constructor-vs-prototype
Think about statically typed language, things on prototype are static and things on this are instance related.
When you use prototype, the function will only be loaded only once into memory (independently on the amount of objects you create) and you can override the function whenever you want.

What is the difference between .prototype and this. in defining methods in Javascript? [duplicate]

What's the difference between
var A = function () {
this.x = function () {
//do something
};
};
and
var A = function () { };
A.prototype.x = function () {
//do something
};
The examples have very different outcomes.
Before looking at the differences, the following should be noted:
A constructor's prototype provides a way to share methods and values among instances via the instance's private [[Prototype]] property.
A function's this is set by how the function is called or by the use of bind (not discussed here). Where a function is called on an object (e.g. myObj.method()) then this within the method references the object. Where this is not set by the call or by the use of bind, it defaults to the global object (window in a browser) or in strict mode, remains undefined.
JavaScript is an object-oriented language, i.e. most values are objects, including functions. (Strings, numbers, and booleans are not objects.)
So here are the snippets in question:
var A = function () {
this.x = function () {
//do something
};
};
In this case, variable A is assigned a value that is a reference to a function. When that function is called using A(), the function's this isn't set by the call so it defaults to the global object and the expression this.x is effective window.x. The result is that a reference to the function expression on the right-hand side is assigned to window.x.
In the case of:
var A = function () { };
A.prototype.x = function () {
//do something
};
something very different occurs. In the first line, variable A is assigned a reference to a function. In JavaScript, all functions objects have a prototype property by default so there is no separate code to create an A.prototype object.
In the second line, A.prototype.x is assigned a reference to a function. This will create an x property if it doesn't exist, or assign a new value if it does. So the difference with the first example in which object's x property is involved in the expression.
Another example is below. It's similar to the first one (and maybe what you meant to ask about):
var A = new function () {
this.x = function () {
//do something
};
};
In this example, the new operator has been added before the function expression so that the function is called as a constructor. When called with new, the function's this is set to reference a new Object whose private [[Prototype]] property is set to reference the constructor's public prototype. So in the assignment statement, the x property will be created on this new object. When called as a constructor, a function returns its this object by default, so there is no need for a separate return this; statement.
To check that A has an x property:
console.log(A.x) // function () {
// //do something
// };
This is an uncommon use of new since the only way to reference the constructor is via A.constructor. It would be much more common to do:
var A = function () {
this.x = function () {
//do something
};
};
var a = new A();
Another way of achieving a similar result is to use an immediately invoked function expression:
var A = (function () {
this.x = function () {
//do something
};
}());
In this case, A assigned the return value of calling the function on the right-hand side. Here again, since this is not set in the call, it will reference the global object and this.x is effective window.x. Since the function doesn't return anything, A will have a value of undefined.
These differences between the two approaches also manifest if you're serializing and de-serializing your Javascript objects to/from JSON. Methods defined on an object's prototype are not serialized when you serialize the object, which can be convenient when for example you want to serialize just the data portions of an object, but not it's methods:
var A = function () {
this.objectsOwnProperties = "are serialized";
};
A.prototype.prototypeProperties = "are NOT serialized";
var instance = new A();
console.log(instance.prototypeProperties); // "are NOT serialized"
console.log(JSON.stringify(instance));
// {"objectsOwnProperties":"are serialized"}
Related questions:
What does it mean that JavaScript is a prototypal language?
What is the scope of a function in JavaScript?
How does the "this" keyword work?
Sidenote: There may not be any significant memory savings between the two approaches, however using the prototype to share methods and properties will likely use less memory than each instance having its own copy.
JavaScript isn't a low-level language. It may not be very valuable to think of prototyping or other inheritance patterns as a way to explicitly change the way memory is allocated.
As others have said the first version, using "this" results in every instance of the class A having its own independent copy of function method "x". Whereas using "prototype" will mean that each instance of class A will use the same copy of method "x".
Here is some code to show this subtle difference:
// x is a method assigned to the object using "this"
var A = function () {
this.x = function () { alert('A'); };
};
A.prototype.updateX = function( value ) {
this.x = function() { alert( value ); }
};
var a1 = new A();
var a2 = new A();
a1.x(); // Displays 'A'
a2.x(); // Also displays 'A'
a1.updateX('Z');
a1.x(); // Displays 'Z'
a2.x(); // Still displays 'A'
// Here x is a method assigned to the object using "prototype"
var B = function () { };
B.prototype.x = function () { alert('B'); };
B.prototype.updateX = function( value ) {
B.prototype.x = function() { alert( value ); }
}
var b1 = new B();
var b2 = new B();
b1.x(); // Displays 'B'
b2.x(); // Also displays 'B'
b1.updateX('Y');
b1.x(); // Displays 'Y'
b2.x(); // Also displays 'Y' because by using prototype we have changed it for all instances
As others have mentioned, there are various reasons to choose one method or the other. My sample is just meant to clearly demonstrate the difference.
Take these 2 examples:
var A = function() { this.hey = function() { alert('from A') } };
vs.
var A = function() {}
A.prototype.hey = function() { alert('from prototype') };
Most people here (especially the top-rated answers) tried to explain how they are different without explaining WHY. I think this is wrong and if you understand the fundamentals first, the difference will become obvious. Let's try to explain the fundamentals first...
a) A function is an object in JavaScript. EVERY object in JavaScript gets an internal property (meaning, you can't access it like other properties, except maybe in browsers like Chrome), often referred to as __proto__ (you can actually type anyObject.__proto__ in Chrome to see what it references. This is just that, a property, nothing more. A property in JavaScript = a variable inside an object, nothing more. What do variables do? They point to things.
So what does this __proto__ property points to? Well, usually another object (we'll explain why later). The only way to force JavaScript for the __proto__ property to NOT point to another object is to use var newObj = Object.create(null). Even if you do this, the __proto__ property STILL exists as a property of the object, just it doesn't point to another object, it points to null.
Here's where most people get confused:
When you create a new function in JavaScript (which is an object as well, remember?), the moment it is defined, JavaScript automatically creates a new property on that function called prototype. Try it:
var A = [];
A.prototype // undefined
A = function() {}
A.prototype // {} // got created when function() {} was defined
A.prototype is TOTALLY DIFFERENT from the __proto__ property. In our example, 'A' now has TWO properties called 'prototype' and __proto__ . This is a big confusion for people. prototype and __proto__ properties are in no way related, they're separate things pointing to separate values.
You may wonder: Why does JavaScript has __proto__ property created on every single object? Well, one word: delegation. When you call a property on an object and the object doesn't have it, then JavaScript looks for the object referenced by __proto__ to see if it maybe has it. If it doesn't have it, then it looks at that object's __proto__ property and so on...until the chain ends. Thus the name prototype chain. Of course, if __proto__ doesn't point to an object and instead points to null, well tough luck, JavaScript realizes that and will return you undefined for the property.
You may also wonder, why does JavaScript creates a property called prototype for a function when you define the function? Because it tries to fool you, yes fool you that it works like class-based languages.
Let's go on with our example and create an "object" out of A:
var a1 = new A();
There's something happening in the background when this thing happened. a1 is an ordinary variable which was assigned a new, empty object.
The fact that you used the operator new before a function invocation A() did something ADDITIONAL in the background. The new keyword created a new object which now references a1 and that object is empty. Here's what happening additionally:
We said that on each function definition there's a new property created called prototype (which you can access it, unlike with the __proto__ property) created? Well, that property is being used now.
So we're now at the point where we have a freshly baked empty a1 object. We said that all objects in JavaScript have an internal __proto__ property which points to something (a1 also has it), whether it's null or another object. What the new operator does is that it sets that __proto__ property to point to the function's prototype property. Read that again. It's basically this:
a1.__proto__ = A.prototype;
We said that A.prototype is nothing more than an empty object (unless we change it to something else before defining a1). So now basically a1.__proto__ points to the same thing A.prototype points to, which is that empty object. They both point to the same object which was created when this line happened:
A = function() {} // JS: cool. let's also create A.prototype pointing to empty {}
Now, there's another thing happening when var a1 = new A() statement is processed. Basically A() is executed and if A is something like this:
var A = function() { this.hey = function() { alert('from A') } };
All that stuff inside function() { } is going to execute. When you reach the this.hey.. line, this is changed to a1 and you get this:
a1.hey = function() { alert('from A') }
I won't cover why this changes to a1 but this is a great answer to learn more.
So to summarize, when you do var a1 = new A() there are 3 things happening in the background:
A totally new empty object is created and assigned to a1. a1 = {}
a1.__proto__ property is assigned to point at the same thing as A.prototype points to (another empty object {} )
The function A() is being executed with this set to the new, empty object created in step 1 (read the answer I referenced above as to why this changes to a1)
Now, let's try to create another object:
var a2 = new A();
Steps 1,2,3 will repeat. Do you notice something? The key word is repeat. Step 1: a2 will be a new empty object, step 2: its __proto__ property will point to the same thing A.prototype points to and most importantly, step 3: function A() is AGAIN executed, which means that a2 will get hey property containing a function. a1 and a2 have two SEPARATE properties named hey which point to 2 SEPARATE functions! We now have duplicate functions in same two different objects doing the same thing, oops...You can imagine the memory implications of this if we have 1000 objects created with new A, after all functions declarations take more memory than something like the number 2. So how do we prevent this?
Remember why the __proto__ property exists on every object? So that if you retrieve the yoMan property on a1 (which doesn't exist), its __proto__ property will be consulted, which if it's an object (and is most cases it is), it will check if it contains yoMan, and if it doesn't, it will consult that object's __proto__ etc. If it does, it will take that property value and display it to you.
So someone decided to use this fact + the fact that when you create a1, its __proto__ property points to the same (empty) object A.prototype points to and do this:
var A = function() {}
A.prototype.hey = function() { alert('from prototype') };
Cool! Now, when you create a1, it again goes through all of the 3 steps above, and in step 3, it doesn't do anything, since function A() has nothing to execute. And if we do:
a1.hey
It will see that a1 does not contain hey and it will check its __proto__ property object to see if it has it, which is the case.
With this approach we eliminate the part from step 3 where functions are duplicated on each new object creation. Instead of a1 and a2 having a separate hey property, now NONE of them has it. Which, I guess, you figured out yourself by now. That's the nice thing...if you understand __proto__ and Function.prototype, questions like these will be pretty obvious.
NOTE: Some people tend to not call the internal Prototype property as __proto__, I've used this name through the post to distinguish it clearly to the Functional.prototype property as two different things.
In most cases they are essentially the same, but the second version saves memory because there is only one instance of the function instead of a separate function for each object.
A reason to use the first form is to access "private members". For example:
var A = function () {
var private_var = ...;
this.x = function () {
return private_var;
};
this.setX = function (new_x) {
private_var = new_x;
};
};
Because of javascript's scoping rules, private_var is available to the function assigned to this.x, but not outside the object.
The first example changes the interface for that object only. The second example changes the interface for all object of that class.
The ultimate problem with using this instead of prototype is that when overriding a method, the constructor of the base class will still refer to the overridden method. Consider this:
BaseClass = function() {
var text = null;
this.setText = function(value) {
text = value + " BaseClass!";
};
this.getText = function() {
return text;
};
this.setText("Hello"); // This always calls BaseClass.setText()
};
SubClass = function() {
// setText is not overridden yet,
// so the constructor calls the superclass' method
BaseClass.call(this);
// Keeping a reference to the superclass' method
var super_setText = this.setText;
// Overriding
this.setText = function(value) {
super_setText.call(this, "SubClass says: " + value);
};
};
SubClass.prototype = new BaseClass();
var subClass = new SubClass();
console.log(subClass.getText()); // Hello BaseClass!
subClass.setText("Hello"); // setText is already overridden
console.log(subClass.getText()); // SubClass says: Hello BaseClass!
versus:
BaseClass = function() {
this.setText("Hello"); // This calls the overridden method
};
BaseClass.prototype.setText = function(value) {
this.text = value + " BaseClass!";
};
BaseClass.prototype.getText = function() {
return this.text;
};
SubClass = function() {
// setText is already overridden, so this works as expected
BaseClass.call(this);
};
SubClass.prototype = new BaseClass();
SubClass.prototype.setText = function(value) {
BaseClass.prototype.setText.call(this, "SubClass says: " + value);
};
var subClass = new SubClass();
console.log(subClass.getText()); // SubClass says: Hello BaseClass!
If you think this is not a problem, then it depends on whether you can live without private variables, and whether you are experienced enough to know a leak when you see one. Also, having to put the constructor logic after the method definitions is inconvenient.
var A = function (param1) {
var privateVar = null; // Private variable
// Calling this.setPrivateVar(param1) here would be an error
this.setPrivateVar = function (value) {
privateVar = value;
console.log("setPrivateVar value set to: " + value);
// param1 is still here, possible memory leak
console.log("setPrivateVar has param1: " + param1);
};
// The constructor logic starts here possibly after
// many lines of code that define methods
this.setPrivateVar(param1); // This is valid
};
var a = new A(0);
// setPrivateVar value set to: 0
// setPrivateVar has param1: 0
a.setPrivateVar(1);
//setPrivateVar value set to: 1
//setPrivateVar has param1: 0
versus:
var A = function (param1) {
this.setPublicVar(param1); // This is valid
};
A.prototype.setPublicVar = function (value) {
this.publicVar = value; // No private variable
};
var a = new A(0);
a.setPublicVar(1);
console.log(a.publicVar); // 1
Every object is linked to a prototype object. When trying to access a property that does not exist, JavaScript will look in the object's prototype object for that property and return it if it exists.
The prototype property of a function constructor refers to the prototype object of all instances created with that function when using new.
In your first example, you are adding a property x to each instance created with the A function.
var A = function () {
this.x = function () {
//do something
};
};
var a = new A(); // constructor function gets executed
// newly created object gets an 'x' property
// which is a function
a.x(); // and can be called like this
In the second example you are adding a property to the prototype object that all the instances created with A point to.
var A = function () { };
A.prototype.x = function () {
//do something
};
var a = new A(); // constructor function gets executed
// which does nothing in this example
a.x(); // you are trying to access the 'x' property of an instance of 'A'
// which does not exist
// so JavaScript looks for that property in the prototype object
// that was defined using the 'prototype' property of the constructor
In conclusion, in the first example a copy of the function is assigned to each instance. In the second example a single copy of the function is shared by all instances.
What's the difference? => A lot.
I think, the this version is used to enable encapsulation, i.e. data hiding.
It helps to manipulate private variables.
Let us look at the following example:
var AdultPerson = function() {
var age;
this.setAge = function(val) {
// some housekeeping
age = val >= 18 && val;
};
this.getAge = function() {
return age;
};
this.isValid = function() {
return !!age;
};
};
Now, the prototype structure can be applied as following:
Different adults have different ages, but all of the adults get the same rights.
So, we add it using prototype, rather than this.
AdultPerson.prototype.getRights = function() {
// Should be valid
return this.isValid() && ['Booze', 'Drive'];
};
Lets look at the implementation now.
var p1 = new AdultPerson;
p1.setAge(12); // ( age = false )
console.log(p1.getRights()); // false ( Kid alert! )
p1.setAge(19); // ( age = 19 )
console.log(p1.getRights()); // ['Booze', 'Drive'] ( Welcome AdultPerson )
var p2 = new AdultPerson;
p2.setAge(45);
console.log(p2.getRights()); // The same getRights() method, *** not a new copy of it ***
Hope this helps.
I know this has been answered to death but I'd like to show an actual example of speed differences.
Function directly on object:
function ExampleFn() {
this.print = function() {
console.log("Calling print! ");
}
}
var objects = [];
console.time('x');
for (let i = 0; i < 2000000; i++) {
objects.push(new ExampleFn());
}
console.timeEnd('x');
//x: 1151.960693359375ms
Function on prototype:
function ExampleFn() {
}
ExampleFn.prototype.print = function() {
console.log("Calling print!");
}
var objects = [];
console.time('y');
for (let i = 0; i < 2000000; i++) {
objects.push(new ExampleFn());
}
console.timeEnd('y');
//x: 617.866943359375ms
Here we're creating 2,000,000 new objects with a print method in Chrome. We're storing every object in an array. Putting print on the prototype takes about 1/2 as long.
Prototype is the template of the class; which applies to all future instances of it. Whereas this is the particular instance of the object.
Let me give you a more comprehensive answer that I learned during a JavaScript training course.
Most answers mentioned the difference already, i.e. when prototyping the function is shared with all (future) instances. Whereas declaring the function in the class will create a copy for each instance.
In general there is no right or wrong, it's more a matter of taste or a design decision depending on your requirements. The prototype however is the technique that is used to develop in an object oriented manner, as I hope you'll see at the end of this answer.
You showed two patterns in your question. I will try to explain two more and try to explain the differences if relevant. Feel free to edit/extend.
In all examples it is about a car object that has a location and can move.
Object Decorator pattern
Not sure if this pattern is still relevant nowadays, but it exists. And it is good to know about it.
You simply pass an object and a property to the decorator function. The decorator returns the object with property and method.
var carlike = function(obj, loc) {
obj.loc = loc;
obj.move = function() {
obj.loc++;
};
return obj;
};
var amy = carlike({}, 1);
amy.move();
var ben = carlike({}, 9);
ben.move();
Functional Classes
A function in JavaScript is a specialised object. In addition to being invoked, a function can store properties like any other object.
In this case Car is a function (also think object) that can be invoked as you are used to do. It has a property methods (which is an object with a move function). When Car is invoked the extend function is called, which does some magic, and extends the Car function (think object) with the methods defined within methods.
This example, though different, comes closest to the first example in the question.
var Car = function(loc) {
var obj = {loc: loc};
extend(obj, Car.methods);
return obj;
};
Car.methods = {
move : function() {
this.loc++;
}
};
var amy = Car(1);
amy.move();
var ben = Car(9);
ben.move();
Prototypal Classes
The first two patterns allow a discussion of using techniques to define shared methods or using methods that are defined inline in the body of the constructor. In both cases every instance has its own move function.
The prototypal pattern does not lend itself well to the same examination, because function sharing via a prototype delegation is the very goal for the prototypal pattern. As others pointed out, it is expected to have a better memory footprint.
However there is one point interesting to know:
Every prototype object has has a convenience property constructor, which points back to the function (think object) it came attached to.
Concerning the last three lines:
In this example Car links to the prototype object, which links via constructor to Car itself, i.e. Car.prototype.constructor is Car itself. This allows you to figure out which constructor function built a certain object.
amy.constructor's lookup fails and thus is delegated to Car.prototype, which does have the constructor property. And so amy.constructor is Car.
Furthermore, amy is an instanceof Car. The instanceof operator works by seeing if the right operand's prototype object (Car) can be found anywhere in the left operand's prototype (amy) chain.
var Car = function(loc) {
var obj = Object.create(Car.prototype);
obj.loc = loc;
return obj;
};
Car.prototype.move = function() {
this.loc++;
};
var amy = Car(1);
amy.move();
var ben = Car(9);
ben.move();
console.log(Car.prototype.constructor);
console.log(amy.constructor);
console.log(amy instanceof Car);
Some developers can be confused in the beginning. See below example:
var Dog = function() {
return {legs: 4, bark: alert};
};
var fido = Dog();
console.log(fido instanceof Dog);
The instanceof operator returns false, because Dog's prototype cannot be found anywhere in fido's prototype chain. fido is a simple object that is created with an object literal, i.e. it just delegates to Object.prototype.
Pseudoclassical patterns
This is really just another form of the prototypal pattern in simplified form and more familiar to do those who program in Java for example, since it uses the new constructor.
It does the same as in the prototypal pattern really, it is just syntactic sugar overtop of the prototypal pattern.
However, the primary difference is that there are optimizations implemented in JavaScript engines that only apply when using the pseudoclassical pattern. Think of the pseudoclassical pattern a probably faster version of the prototypal pattern; the object relations in both examples are the same.
var Car = function(loc) {
this.loc = loc;
};
Car.prototype.move = function() {
this.loc++;
};
var amy = new Car(1);
amy.move();
var ben = new Car(9);
ben.move();
Finally, it should not be too difficult to realize how object oriented programming can be done. There are two sections.
One section that defines common properties/methods in the prototype (chain).
And another section where you put the definitions that distinguish the objects from each other (loc variable in the examples).
This is what allows us to apply concepts like superclass or subclass in JavaScript.
Feel free to add or edit. Once more complete I could make this a community wiki maybe.
I believe that #Matthew Crumley is right. They are functionally, if not structurally, equivalent. If you use Firebug to look at the objects that are created using new, you can see that they are the same. However, my preference would be the following. I'm guessing that it just seems more like what I'm used to in C#/Java. That is, define the class, define the fields, constructor, and methods.
var A = function() {};
A.prototype = {
_instance_var: 0,
initialize: function(v) { this._instance_var = v; },
x: function() { alert(this._instance_var); }
};
EDIT Didn't mean to imply that the scope of the variable was private, I was just trying to illustrate how I define my classes in javascript. Variable name has been changed to reflect this.
As discussed in other answers, it's really a performance consideration because the function in the prototype is shared with all of the instantiations - rather than the function being created for each instantiation.
I put together a jsperf to show this. There is a dramatic difference in the time it takes to instantiate the class, although it is really only relevant if you are making many instances.
http://jsperf.com/functions-in-constructor-vs-prototype
Think about statically typed language, things on prototype are static and things on this are instance related.
When you use prototype, the function will only be loaded only once into memory (independently on the amount of objects you create) and you can override the function whenever you want.

How to properly define a method for an object in JavaScript [duplicate]

What's the difference between
var A = function () {
this.x = function () {
//do something
};
};
and
var A = function () { };
A.prototype.x = function () {
//do something
};
The examples have very different outcomes.
Before looking at the differences, the following should be noted:
A constructor's prototype provides a way to share methods and values among instances via the instance's private [[Prototype]] property.
A function's this is set by how the function is called or by the use of bind (not discussed here). Where a function is called on an object (e.g. myObj.method()) then this within the method references the object. Where this is not set by the call or by the use of bind, it defaults to the global object (window in a browser) or in strict mode, remains undefined.
JavaScript is an object-oriented language, i.e. most values are objects, including functions. (Strings, numbers, and booleans are not objects.)
So here are the snippets in question:
var A = function () {
this.x = function () {
//do something
};
};
In this case, variable A is assigned a value that is a reference to a function. When that function is called using A(), the function's this isn't set by the call so it defaults to the global object and the expression this.x is effective window.x. The result is that a reference to the function expression on the right-hand side is assigned to window.x.
In the case of:
var A = function () { };
A.prototype.x = function () {
//do something
};
something very different occurs. In the first line, variable A is assigned a reference to a function. In JavaScript, all functions objects have a prototype property by default so there is no separate code to create an A.prototype object.
In the second line, A.prototype.x is assigned a reference to a function. This will create an x property if it doesn't exist, or assign a new value if it does. So the difference with the first example in which object's x property is involved in the expression.
Another example is below. It's similar to the first one (and maybe what you meant to ask about):
var A = new function () {
this.x = function () {
//do something
};
};
In this example, the new operator has been added before the function expression so that the function is called as a constructor. When called with new, the function's this is set to reference a new Object whose private [[Prototype]] property is set to reference the constructor's public prototype. So in the assignment statement, the x property will be created on this new object. When called as a constructor, a function returns its this object by default, so there is no need for a separate return this; statement.
To check that A has an x property:
console.log(A.x) // function () {
// //do something
// };
This is an uncommon use of new since the only way to reference the constructor is via A.constructor. It would be much more common to do:
var A = function () {
this.x = function () {
//do something
};
};
var a = new A();
Another way of achieving a similar result is to use an immediately invoked function expression:
var A = (function () {
this.x = function () {
//do something
};
}());
In this case, A assigned the return value of calling the function on the right-hand side. Here again, since this is not set in the call, it will reference the global object and this.x is effective window.x. Since the function doesn't return anything, A will have a value of undefined.
These differences between the two approaches also manifest if you're serializing and de-serializing your Javascript objects to/from JSON. Methods defined on an object's prototype are not serialized when you serialize the object, which can be convenient when for example you want to serialize just the data portions of an object, but not it's methods:
var A = function () {
this.objectsOwnProperties = "are serialized";
};
A.prototype.prototypeProperties = "are NOT serialized";
var instance = new A();
console.log(instance.prototypeProperties); // "are NOT serialized"
console.log(JSON.stringify(instance));
// {"objectsOwnProperties":"are serialized"}
Related questions:
What does it mean that JavaScript is a prototypal language?
What is the scope of a function in JavaScript?
How does the "this" keyword work?
Sidenote: There may not be any significant memory savings between the two approaches, however using the prototype to share methods and properties will likely use less memory than each instance having its own copy.
JavaScript isn't a low-level language. It may not be very valuable to think of prototyping or other inheritance patterns as a way to explicitly change the way memory is allocated.
As others have said the first version, using "this" results in every instance of the class A having its own independent copy of function method "x". Whereas using "prototype" will mean that each instance of class A will use the same copy of method "x".
Here is some code to show this subtle difference:
// x is a method assigned to the object using "this"
var A = function () {
this.x = function () { alert('A'); };
};
A.prototype.updateX = function( value ) {
this.x = function() { alert( value ); }
};
var a1 = new A();
var a2 = new A();
a1.x(); // Displays 'A'
a2.x(); // Also displays 'A'
a1.updateX('Z');
a1.x(); // Displays 'Z'
a2.x(); // Still displays 'A'
// Here x is a method assigned to the object using "prototype"
var B = function () { };
B.prototype.x = function () { alert('B'); };
B.prototype.updateX = function( value ) {
B.prototype.x = function() { alert( value ); }
}
var b1 = new B();
var b2 = new B();
b1.x(); // Displays 'B'
b2.x(); // Also displays 'B'
b1.updateX('Y');
b1.x(); // Displays 'Y'
b2.x(); // Also displays 'Y' because by using prototype we have changed it for all instances
As others have mentioned, there are various reasons to choose one method or the other. My sample is just meant to clearly demonstrate the difference.
Take these 2 examples:
var A = function() { this.hey = function() { alert('from A') } };
vs.
var A = function() {}
A.prototype.hey = function() { alert('from prototype') };
Most people here (especially the top-rated answers) tried to explain how they are different without explaining WHY. I think this is wrong and if you understand the fundamentals first, the difference will become obvious. Let's try to explain the fundamentals first...
a) A function is an object in JavaScript. EVERY object in JavaScript gets an internal property (meaning, you can't access it like other properties, except maybe in browsers like Chrome), often referred to as __proto__ (you can actually type anyObject.__proto__ in Chrome to see what it references. This is just that, a property, nothing more. A property in JavaScript = a variable inside an object, nothing more. What do variables do? They point to things.
So what does this __proto__ property points to? Well, usually another object (we'll explain why later). The only way to force JavaScript for the __proto__ property to NOT point to another object is to use var newObj = Object.create(null). Even if you do this, the __proto__ property STILL exists as a property of the object, just it doesn't point to another object, it points to null.
Here's where most people get confused:
When you create a new function in JavaScript (which is an object as well, remember?), the moment it is defined, JavaScript automatically creates a new property on that function called prototype. Try it:
var A = [];
A.prototype // undefined
A = function() {}
A.prototype // {} // got created when function() {} was defined
A.prototype is TOTALLY DIFFERENT from the __proto__ property. In our example, 'A' now has TWO properties called 'prototype' and __proto__ . This is a big confusion for people. prototype and __proto__ properties are in no way related, they're separate things pointing to separate values.
You may wonder: Why does JavaScript has __proto__ property created on every single object? Well, one word: delegation. When you call a property on an object and the object doesn't have it, then JavaScript looks for the object referenced by __proto__ to see if it maybe has it. If it doesn't have it, then it looks at that object's __proto__ property and so on...until the chain ends. Thus the name prototype chain. Of course, if __proto__ doesn't point to an object and instead points to null, well tough luck, JavaScript realizes that and will return you undefined for the property.
You may also wonder, why does JavaScript creates a property called prototype for a function when you define the function? Because it tries to fool you, yes fool you that it works like class-based languages.
Let's go on with our example and create an "object" out of A:
var a1 = new A();
There's something happening in the background when this thing happened. a1 is an ordinary variable which was assigned a new, empty object.
The fact that you used the operator new before a function invocation A() did something ADDITIONAL in the background. The new keyword created a new object which now references a1 and that object is empty. Here's what happening additionally:
We said that on each function definition there's a new property created called prototype (which you can access it, unlike with the __proto__ property) created? Well, that property is being used now.
So we're now at the point where we have a freshly baked empty a1 object. We said that all objects in JavaScript have an internal __proto__ property which points to something (a1 also has it), whether it's null or another object. What the new operator does is that it sets that __proto__ property to point to the function's prototype property. Read that again. It's basically this:
a1.__proto__ = A.prototype;
We said that A.prototype is nothing more than an empty object (unless we change it to something else before defining a1). So now basically a1.__proto__ points to the same thing A.prototype points to, which is that empty object. They both point to the same object which was created when this line happened:
A = function() {} // JS: cool. let's also create A.prototype pointing to empty {}
Now, there's another thing happening when var a1 = new A() statement is processed. Basically A() is executed and if A is something like this:
var A = function() { this.hey = function() { alert('from A') } };
All that stuff inside function() { } is going to execute. When you reach the this.hey.. line, this is changed to a1 and you get this:
a1.hey = function() { alert('from A') }
I won't cover why this changes to a1 but this is a great answer to learn more.
So to summarize, when you do var a1 = new A() there are 3 things happening in the background:
A totally new empty object is created and assigned to a1. a1 = {}
a1.__proto__ property is assigned to point at the same thing as A.prototype points to (another empty object {} )
The function A() is being executed with this set to the new, empty object created in step 1 (read the answer I referenced above as to why this changes to a1)
Now, let's try to create another object:
var a2 = new A();
Steps 1,2,3 will repeat. Do you notice something? The key word is repeat. Step 1: a2 will be a new empty object, step 2: its __proto__ property will point to the same thing A.prototype points to and most importantly, step 3: function A() is AGAIN executed, which means that a2 will get hey property containing a function. a1 and a2 have two SEPARATE properties named hey which point to 2 SEPARATE functions! We now have duplicate functions in same two different objects doing the same thing, oops...You can imagine the memory implications of this if we have 1000 objects created with new A, after all functions declarations take more memory than something like the number 2. So how do we prevent this?
Remember why the __proto__ property exists on every object? So that if you retrieve the yoMan property on a1 (which doesn't exist), its __proto__ property will be consulted, which if it's an object (and is most cases it is), it will check if it contains yoMan, and if it doesn't, it will consult that object's __proto__ etc. If it does, it will take that property value and display it to you.
So someone decided to use this fact + the fact that when you create a1, its __proto__ property points to the same (empty) object A.prototype points to and do this:
var A = function() {}
A.prototype.hey = function() { alert('from prototype') };
Cool! Now, when you create a1, it again goes through all of the 3 steps above, and in step 3, it doesn't do anything, since function A() has nothing to execute. And if we do:
a1.hey
It will see that a1 does not contain hey and it will check its __proto__ property object to see if it has it, which is the case.
With this approach we eliminate the part from step 3 where functions are duplicated on each new object creation. Instead of a1 and a2 having a separate hey property, now NONE of them has it. Which, I guess, you figured out yourself by now. That's the nice thing...if you understand __proto__ and Function.prototype, questions like these will be pretty obvious.
NOTE: Some people tend to not call the internal Prototype property as __proto__, I've used this name through the post to distinguish it clearly to the Functional.prototype property as two different things.
In most cases they are essentially the same, but the second version saves memory because there is only one instance of the function instead of a separate function for each object.
A reason to use the first form is to access "private members". For example:
var A = function () {
var private_var = ...;
this.x = function () {
return private_var;
};
this.setX = function (new_x) {
private_var = new_x;
};
};
Because of javascript's scoping rules, private_var is available to the function assigned to this.x, but not outside the object.
The first example changes the interface for that object only. The second example changes the interface for all object of that class.
The ultimate problem with using this instead of prototype is that when overriding a method, the constructor of the base class will still refer to the overridden method. Consider this:
BaseClass = function() {
var text = null;
this.setText = function(value) {
text = value + " BaseClass!";
};
this.getText = function() {
return text;
};
this.setText("Hello"); // This always calls BaseClass.setText()
};
SubClass = function() {
// setText is not overridden yet,
// so the constructor calls the superclass' method
BaseClass.call(this);
// Keeping a reference to the superclass' method
var super_setText = this.setText;
// Overriding
this.setText = function(value) {
super_setText.call(this, "SubClass says: " + value);
};
};
SubClass.prototype = new BaseClass();
var subClass = new SubClass();
console.log(subClass.getText()); // Hello BaseClass!
subClass.setText("Hello"); // setText is already overridden
console.log(subClass.getText()); // SubClass says: Hello BaseClass!
versus:
BaseClass = function() {
this.setText("Hello"); // This calls the overridden method
};
BaseClass.prototype.setText = function(value) {
this.text = value + " BaseClass!";
};
BaseClass.prototype.getText = function() {
return this.text;
};
SubClass = function() {
// setText is already overridden, so this works as expected
BaseClass.call(this);
};
SubClass.prototype = new BaseClass();
SubClass.prototype.setText = function(value) {
BaseClass.prototype.setText.call(this, "SubClass says: " + value);
};
var subClass = new SubClass();
console.log(subClass.getText()); // SubClass says: Hello BaseClass!
If you think this is not a problem, then it depends on whether you can live without private variables, and whether you are experienced enough to know a leak when you see one. Also, having to put the constructor logic after the method definitions is inconvenient.
var A = function (param1) {
var privateVar = null; // Private variable
// Calling this.setPrivateVar(param1) here would be an error
this.setPrivateVar = function (value) {
privateVar = value;
console.log("setPrivateVar value set to: " + value);
// param1 is still here, possible memory leak
console.log("setPrivateVar has param1: " + param1);
};
// The constructor logic starts here possibly after
// many lines of code that define methods
this.setPrivateVar(param1); // This is valid
};
var a = new A(0);
// setPrivateVar value set to: 0
// setPrivateVar has param1: 0
a.setPrivateVar(1);
//setPrivateVar value set to: 1
//setPrivateVar has param1: 0
versus:
var A = function (param1) {
this.setPublicVar(param1); // This is valid
};
A.prototype.setPublicVar = function (value) {
this.publicVar = value; // No private variable
};
var a = new A(0);
a.setPublicVar(1);
console.log(a.publicVar); // 1
Every object is linked to a prototype object. When trying to access a property that does not exist, JavaScript will look in the object's prototype object for that property and return it if it exists.
The prototype property of a function constructor refers to the prototype object of all instances created with that function when using new.
In your first example, you are adding a property x to each instance created with the A function.
var A = function () {
this.x = function () {
//do something
};
};
var a = new A(); // constructor function gets executed
// newly created object gets an 'x' property
// which is a function
a.x(); // and can be called like this
In the second example you are adding a property to the prototype object that all the instances created with A point to.
var A = function () { };
A.prototype.x = function () {
//do something
};
var a = new A(); // constructor function gets executed
// which does nothing in this example
a.x(); // you are trying to access the 'x' property of an instance of 'A'
// which does not exist
// so JavaScript looks for that property in the prototype object
// that was defined using the 'prototype' property of the constructor
In conclusion, in the first example a copy of the function is assigned to each instance. In the second example a single copy of the function is shared by all instances.
What's the difference? => A lot.
I think, the this version is used to enable encapsulation, i.e. data hiding.
It helps to manipulate private variables.
Let us look at the following example:
var AdultPerson = function() {
var age;
this.setAge = function(val) {
// some housekeeping
age = val >= 18 && val;
};
this.getAge = function() {
return age;
};
this.isValid = function() {
return !!age;
};
};
Now, the prototype structure can be applied as following:
Different adults have different ages, but all of the adults get the same rights.
So, we add it using prototype, rather than this.
AdultPerson.prototype.getRights = function() {
// Should be valid
return this.isValid() && ['Booze', 'Drive'];
};
Lets look at the implementation now.
var p1 = new AdultPerson;
p1.setAge(12); // ( age = false )
console.log(p1.getRights()); // false ( Kid alert! )
p1.setAge(19); // ( age = 19 )
console.log(p1.getRights()); // ['Booze', 'Drive'] ( Welcome AdultPerson )
var p2 = new AdultPerson;
p2.setAge(45);
console.log(p2.getRights()); // The same getRights() method, *** not a new copy of it ***
Hope this helps.
I know this has been answered to death but I'd like to show an actual example of speed differences.
Function directly on object:
function ExampleFn() {
this.print = function() {
console.log("Calling print! ");
}
}
var objects = [];
console.time('x');
for (let i = 0; i < 2000000; i++) {
objects.push(new ExampleFn());
}
console.timeEnd('x');
//x: 1151.960693359375ms
Function on prototype:
function ExampleFn() {
}
ExampleFn.prototype.print = function() {
console.log("Calling print!");
}
var objects = [];
console.time('y');
for (let i = 0; i < 2000000; i++) {
objects.push(new ExampleFn());
}
console.timeEnd('y');
//x: 617.866943359375ms
Here we're creating 2,000,000 new objects with a print method in Chrome. We're storing every object in an array. Putting print on the prototype takes about 1/2 as long.
Prototype is the template of the class; which applies to all future instances of it. Whereas this is the particular instance of the object.
Let me give you a more comprehensive answer that I learned during a JavaScript training course.
Most answers mentioned the difference already, i.e. when prototyping the function is shared with all (future) instances. Whereas declaring the function in the class will create a copy for each instance.
In general there is no right or wrong, it's more a matter of taste or a design decision depending on your requirements. The prototype however is the technique that is used to develop in an object oriented manner, as I hope you'll see at the end of this answer.
You showed two patterns in your question. I will try to explain two more and try to explain the differences if relevant. Feel free to edit/extend.
In all examples it is about a car object that has a location and can move.
Object Decorator pattern
Not sure if this pattern is still relevant nowadays, but it exists. And it is good to know about it.
You simply pass an object and a property to the decorator function. The decorator returns the object with property and method.
var carlike = function(obj, loc) {
obj.loc = loc;
obj.move = function() {
obj.loc++;
};
return obj;
};
var amy = carlike({}, 1);
amy.move();
var ben = carlike({}, 9);
ben.move();
Functional Classes
A function in JavaScript is a specialised object. In addition to being invoked, a function can store properties like any other object.
In this case Car is a function (also think object) that can be invoked as you are used to do. It has a property methods (which is an object with a move function). When Car is invoked the extend function is called, which does some magic, and extends the Car function (think object) with the methods defined within methods.
This example, though different, comes closest to the first example in the question.
var Car = function(loc) {
var obj = {loc: loc};
extend(obj, Car.methods);
return obj;
};
Car.methods = {
move : function() {
this.loc++;
}
};
var amy = Car(1);
amy.move();
var ben = Car(9);
ben.move();
Prototypal Classes
The first two patterns allow a discussion of using techniques to define shared methods or using methods that are defined inline in the body of the constructor. In both cases every instance has its own move function.
The prototypal pattern does not lend itself well to the same examination, because function sharing via a prototype delegation is the very goal for the prototypal pattern. As others pointed out, it is expected to have a better memory footprint.
However there is one point interesting to know:
Every prototype object has has a convenience property constructor, which points back to the function (think object) it came attached to.
Concerning the last three lines:
In this example Car links to the prototype object, which links via constructor to Car itself, i.e. Car.prototype.constructor is Car itself. This allows you to figure out which constructor function built a certain object.
amy.constructor's lookup fails and thus is delegated to Car.prototype, which does have the constructor property. And so amy.constructor is Car.
Furthermore, amy is an instanceof Car. The instanceof operator works by seeing if the right operand's prototype object (Car) can be found anywhere in the left operand's prototype (amy) chain.
var Car = function(loc) {
var obj = Object.create(Car.prototype);
obj.loc = loc;
return obj;
};
Car.prototype.move = function() {
this.loc++;
};
var amy = Car(1);
amy.move();
var ben = Car(9);
ben.move();
console.log(Car.prototype.constructor);
console.log(amy.constructor);
console.log(amy instanceof Car);
Some developers can be confused in the beginning. See below example:
var Dog = function() {
return {legs: 4, bark: alert};
};
var fido = Dog();
console.log(fido instanceof Dog);
The instanceof operator returns false, because Dog's prototype cannot be found anywhere in fido's prototype chain. fido is a simple object that is created with an object literal, i.e. it just delegates to Object.prototype.
Pseudoclassical patterns
This is really just another form of the prototypal pattern in simplified form and more familiar to do those who program in Java for example, since it uses the new constructor.
It does the same as in the prototypal pattern really, it is just syntactic sugar overtop of the prototypal pattern.
However, the primary difference is that there are optimizations implemented in JavaScript engines that only apply when using the pseudoclassical pattern. Think of the pseudoclassical pattern a probably faster version of the prototypal pattern; the object relations in both examples are the same.
var Car = function(loc) {
this.loc = loc;
};
Car.prototype.move = function() {
this.loc++;
};
var amy = new Car(1);
amy.move();
var ben = new Car(9);
ben.move();
Finally, it should not be too difficult to realize how object oriented programming can be done. There are two sections.
One section that defines common properties/methods in the prototype (chain).
And another section where you put the definitions that distinguish the objects from each other (loc variable in the examples).
This is what allows us to apply concepts like superclass or subclass in JavaScript.
Feel free to add or edit. Once more complete I could make this a community wiki maybe.
I believe that #Matthew Crumley is right. They are functionally, if not structurally, equivalent. If you use Firebug to look at the objects that are created using new, you can see that they are the same. However, my preference would be the following. I'm guessing that it just seems more like what I'm used to in C#/Java. That is, define the class, define the fields, constructor, and methods.
var A = function() {};
A.prototype = {
_instance_var: 0,
initialize: function(v) { this._instance_var = v; },
x: function() { alert(this._instance_var); }
};
EDIT Didn't mean to imply that the scope of the variable was private, I was just trying to illustrate how I define my classes in javascript. Variable name has been changed to reflect this.
As discussed in other answers, it's really a performance consideration because the function in the prototype is shared with all of the instantiations - rather than the function being created for each instantiation.
I put together a jsperf to show this. There is a dramatic difference in the time it takes to instantiate the class, although it is really only relevant if you are making many instances.
http://jsperf.com/functions-in-constructor-vs-prototype
Think about statically typed language, things on prototype are static and things on this are instance related.
When you use prototype, the function will only be loaded only once into memory (independently on the amount of objects you create) and you can override the function whenever you want.

What the different between "this." and "prototype." on build js Class. [duplicate]

What's the difference between
var A = function () {
this.x = function () {
//do something
};
};
and
var A = function () { };
A.prototype.x = function () {
//do something
};
The examples have very different outcomes.
Before looking at the differences, the following should be noted:
A constructor's prototype provides a way to share methods and values among instances via the instance's private [[Prototype]] property.
A function's this is set by how the function is called or by the use of bind (not discussed here). Where a function is called on an object (e.g. myObj.method()) then this within the method references the object. Where this is not set by the call or by the use of bind, it defaults to the global object (window in a browser) or in strict mode, remains undefined.
JavaScript is an object-oriented language, i.e. most values are objects, including functions. (Strings, numbers, and booleans are not objects.)
So here are the snippets in question:
var A = function () {
this.x = function () {
//do something
};
};
In this case, variable A is assigned a value that is a reference to a function. When that function is called using A(), the function's this isn't set by the call so it defaults to the global object and the expression this.x is effective window.x. The result is that a reference to the function expression on the right-hand side is assigned to window.x.
In the case of:
var A = function () { };
A.prototype.x = function () {
//do something
};
something very different occurs. In the first line, variable A is assigned a reference to a function. In JavaScript, all functions objects have a prototype property by default so there is no separate code to create an A.prototype object.
In the second line, A.prototype.x is assigned a reference to a function. This will create an x property if it doesn't exist, or assign a new value if it does. So the difference with the first example in which object's x property is involved in the expression.
Another example is below. It's similar to the first one (and maybe what you meant to ask about):
var A = new function () {
this.x = function () {
//do something
};
};
In this example, the new operator has been added before the function expression so that the function is called as a constructor. When called with new, the function's this is set to reference a new Object whose private [[Prototype]] property is set to reference the constructor's public prototype. So in the assignment statement, the x property will be created on this new object. When called as a constructor, a function returns its this object by default, so there is no need for a separate return this; statement.
To check that A has an x property:
console.log(A.x) // function () {
// //do something
// };
This is an uncommon use of new since the only way to reference the constructor is via A.constructor. It would be much more common to do:
var A = function () {
this.x = function () {
//do something
};
};
var a = new A();
Another way of achieving a similar result is to use an immediately invoked function expression:
var A = (function () {
this.x = function () {
//do something
};
}());
In this case, A assigned the return value of calling the function on the right-hand side. Here again, since this is not set in the call, it will reference the global object and this.x is effective window.x. Since the function doesn't return anything, A will have a value of undefined.
These differences between the two approaches also manifest if you're serializing and de-serializing your Javascript objects to/from JSON. Methods defined on an object's prototype are not serialized when you serialize the object, which can be convenient when for example you want to serialize just the data portions of an object, but not it's methods:
var A = function () {
this.objectsOwnProperties = "are serialized";
};
A.prototype.prototypeProperties = "are NOT serialized";
var instance = new A();
console.log(instance.prototypeProperties); // "are NOT serialized"
console.log(JSON.stringify(instance));
// {"objectsOwnProperties":"are serialized"}
Related questions:
What does it mean that JavaScript is a prototypal language?
What is the scope of a function in JavaScript?
How does the "this" keyword work?
Sidenote: There may not be any significant memory savings between the two approaches, however using the prototype to share methods and properties will likely use less memory than each instance having its own copy.
JavaScript isn't a low-level language. It may not be very valuable to think of prototyping or other inheritance patterns as a way to explicitly change the way memory is allocated.
As others have said the first version, using "this" results in every instance of the class A having its own independent copy of function method "x". Whereas using "prototype" will mean that each instance of class A will use the same copy of method "x".
Here is some code to show this subtle difference:
// x is a method assigned to the object using "this"
var A = function () {
this.x = function () { alert('A'); };
};
A.prototype.updateX = function( value ) {
this.x = function() { alert( value ); }
};
var a1 = new A();
var a2 = new A();
a1.x(); // Displays 'A'
a2.x(); // Also displays 'A'
a1.updateX('Z');
a1.x(); // Displays 'Z'
a2.x(); // Still displays 'A'
// Here x is a method assigned to the object using "prototype"
var B = function () { };
B.prototype.x = function () { alert('B'); };
B.prototype.updateX = function( value ) {
B.prototype.x = function() { alert( value ); }
}
var b1 = new B();
var b2 = new B();
b1.x(); // Displays 'B'
b2.x(); // Also displays 'B'
b1.updateX('Y');
b1.x(); // Displays 'Y'
b2.x(); // Also displays 'Y' because by using prototype we have changed it for all instances
As others have mentioned, there are various reasons to choose one method or the other. My sample is just meant to clearly demonstrate the difference.
Take these 2 examples:
var A = function() { this.hey = function() { alert('from A') } };
vs.
var A = function() {}
A.prototype.hey = function() { alert('from prototype') };
Most people here (especially the top-rated answers) tried to explain how they are different without explaining WHY. I think this is wrong and if you understand the fundamentals first, the difference will become obvious. Let's try to explain the fundamentals first...
a) A function is an object in JavaScript. EVERY object in JavaScript gets an internal property (meaning, you can't access it like other properties, except maybe in browsers like Chrome), often referred to as __proto__ (you can actually type anyObject.__proto__ in Chrome to see what it references. This is just that, a property, nothing more. A property in JavaScript = a variable inside an object, nothing more. What do variables do? They point to things.
So what does this __proto__ property points to? Well, usually another object (we'll explain why later). The only way to force JavaScript for the __proto__ property to NOT point to another object is to use var newObj = Object.create(null). Even if you do this, the __proto__ property STILL exists as a property of the object, just it doesn't point to another object, it points to null.
Here's where most people get confused:
When you create a new function in JavaScript (which is an object as well, remember?), the moment it is defined, JavaScript automatically creates a new property on that function called prototype. Try it:
var A = [];
A.prototype // undefined
A = function() {}
A.prototype // {} // got created when function() {} was defined
A.prototype is TOTALLY DIFFERENT from the __proto__ property. In our example, 'A' now has TWO properties called 'prototype' and __proto__ . This is a big confusion for people. prototype and __proto__ properties are in no way related, they're separate things pointing to separate values.
You may wonder: Why does JavaScript has __proto__ property created on every single object? Well, one word: delegation. When you call a property on an object and the object doesn't have it, then JavaScript looks for the object referenced by __proto__ to see if it maybe has it. If it doesn't have it, then it looks at that object's __proto__ property and so on...until the chain ends. Thus the name prototype chain. Of course, if __proto__ doesn't point to an object and instead points to null, well tough luck, JavaScript realizes that and will return you undefined for the property.
You may also wonder, why does JavaScript creates a property called prototype for a function when you define the function? Because it tries to fool you, yes fool you that it works like class-based languages.
Let's go on with our example and create an "object" out of A:
var a1 = new A();
There's something happening in the background when this thing happened. a1 is an ordinary variable which was assigned a new, empty object.
The fact that you used the operator new before a function invocation A() did something ADDITIONAL in the background. The new keyword created a new object which now references a1 and that object is empty. Here's what happening additionally:
We said that on each function definition there's a new property created called prototype (which you can access it, unlike with the __proto__ property) created? Well, that property is being used now.
So we're now at the point where we have a freshly baked empty a1 object. We said that all objects in JavaScript have an internal __proto__ property which points to something (a1 also has it), whether it's null or another object. What the new operator does is that it sets that __proto__ property to point to the function's prototype property. Read that again. It's basically this:
a1.__proto__ = A.prototype;
We said that A.prototype is nothing more than an empty object (unless we change it to something else before defining a1). So now basically a1.__proto__ points to the same thing A.prototype points to, which is that empty object. They both point to the same object which was created when this line happened:
A = function() {} // JS: cool. let's also create A.prototype pointing to empty {}
Now, there's another thing happening when var a1 = new A() statement is processed. Basically A() is executed and if A is something like this:
var A = function() { this.hey = function() { alert('from A') } };
All that stuff inside function() { } is going to execute. When you reach the this.hey.. line, this is changed to a1 and you get this:
a1.hey = function() { alert('from A') }
I won't cover why this changes to a1 but this is a great answer to learn more.
So to summarize, when you do var a1 = new A() there are 3 things happening in the background:
A totally new empty object is created and assigned to a1. a1 = {}
a1.__proto__ property is assigned to point at the same thing as A.prototype points to (another empty object {} )
The function A() is being executed with this set to the new, empty object created in step 1 (read the answer I referenced above as to why this changes to a1)
Now, let's try to create another object:
var a2 = new A();
Steps 1,2,3 will repeat. Do you notice something? The key word is repeat. Step 1: a2 will be a new empty object, step 2: its __proto__ property will point to the same thing A.prototype points to and most importantly, step 3: function A() is AGAIN executed, which means that a2 will get hey property containing a function. a1 and a2 have two SEPARATE properties named hey which point to 2 SEPARATE functions! We now have duplicate functions in same two different objects doing the same thing, oops...You can imagine the memory implications of this if we have 1000 objects created with new A, after all functions declarations take more memory than something like the number 2. So how do we prevent this?
Remember why the __proto__ property exists on every object? So that if you retrieve the yoMan property on a1 (which doesn't exist), its __proto__ property will be consulted, which if it's an object (and is most cases it is), it will check if it contains yoMan, and if it doesn't, it will consult that object's __proto__ etc. If it does, it will take that property value and display it to you.
So someone decided to use this fact + the fact that when you create a1, its __proto__ property points to the same (empty) object A.prototype points to and do this:
var A = function() {}
A.prototype.hey = function() { alert('from prototype') };
Cool! Now, when you create a1, it again goes through all of the 3 steps above, and in step 3, it doesn't do anything, since function A() has nothing to execute. And if we do:
a1.hey
It will see that a1 does not contain hey and it will check its __proto__ property object to see if it has it, which is the case.
With this approach we eliminate the part from step 3 where functions are duplicated on each new object creation. Instead of a1 and a2 having a separate hey property, now NONE of them has it. Which, I guess, you figured out yourself by now. That's the nice thing...if you understand __proto__ and Function.prototype, questions like these will be pretty obvious.
NOTE: Some people tend to not call the internal Prototype property as __proto__, I've used this name through the post to distinguish it clearly to the Functional.prototype property as two different things.
In most cases they are essentially the same, but the second version saves memory because there is only one instance of the function instead of a separate function for each object.
A reason to use the first form is to access "private members". For example:
var A = function () {
var private_var = ...;
this.x = function () {
return private_var;
};
this.setX = function (new_x) {
private_var = new_x;
};
};
Because of javascript's scoping rules, private_var is available to the function assigned to this.x, but not outside the object.
The first example changes the interface for that object only. The second example changes the interface for all object of that class.
The ultimate problem with using this instead of prototype is that when overriding a method, the constructor of the base class will still refer to the overridden method. Consider this:
BaseClass = function() {
var text = null;
this.setText = function(value) {
text = value + " BaseClass!";
};
this.getText = function() {
return text;
};
this.setText("Hello"); // This always calls BaseClass.setText()
};
SubClass = function() {
// setText is not overridden yet,
// so the constructor calls the superclass' method
BaseClass.call(this);
// Keeping a reference to the superclass' method
var super_setText = this.setText;
// Overriding
this.setText = function(value) {
super_setText.call(this, "SubClass says: " + value);
};
};
SubClass.prototype = new BaseClass();
var subClass = new SubClass();
console.log(subClass.getText()); // Hello BaseClass!
subClass.setText("Hello"); // setText is already overridden
console.log(subClass.getText()); // SubClass says: Hello BaseClass!
versus:
BaseClass = function() {
this.setText("Hello"); // This calls the overridden method
};
BaseClass.prototype.setText = function(value) {
this.text = value + " BaseClass!";
};
BaseClass.prototype.getText = function() {
return this.text;
};
SubClass = function() {
// setText is already overridden, so this works as expected
BaseClass.call(this);
};
SubClass.prototype = new BaseClass();
SubClass.prototype.setText = function(value) {
BaseClass.prototype.setText.call(this, "SubClass says: " + value);
};
var subClass = new SubClass();
console.log(subClass.getText()); // SubClass says: Hello BaseClass!
If you think this is not a problem, then it depends on whether you can live without private variables, and whether you are experienced enough to know a leak when you see one. Also, having to put the constructor logic after the method definitions is inconvenient.
var A = function (param1) {
var privateVar = null; // Private variable
// Calling this.setPrivateVar(param1) here would be an error
this.setPrivateVar = function (value) {
privateVar = value;
console.log("setPrivateVar value set to: " + value);
// param1 is still here, possible memory leak
console.log("setPrivateVar has param1: " + param1);
};
// The constructor logic starts here possibly after
// many lines of code that define methods
this.setPrivateVar(param1); // This is valid
};
var a = new A(0);
// setPrivateVar value set to: 0
// setPrivateVar has param1: 0
a.setPrivateVar(1);
//setPrivateVar value set to: 1
//setPrivateVar has param1: 0
versus:
var A = function (param1) {
this.setPublicVar(param1); // This is valid
};
A.prototype.setPublicVar = function (value) {
this.publicVar = value; // No private variable
};
var a = new A(0);
a.setPublicVar(1);
console.log(a.publicVar); // 1
Every object is linked to a prototype object. When trying to access a property that does not exist, JavaScript will look in the object's prototype object for that property and return it if it exists.
The prototype property of a function constructor refers to the prototype object of all instances created with that function when using new.
In your first example, you are adding a property x to each instance created with the A function.
var A = function () {
this.x = function () {
//do something
};
};
var a = new A(); // constructor function gets executed
// newly created object gets an 'x' property
// which is a function
a.x(); // and can be called like this
In the second example you are adding a property to the prototype object that all the instances created with A point to.
var A = function () { };
A.prototype.x = function () {
//do something
};
var a = new A(); // constructor function gets executed
// which does nothing in this example
a.x(); // you are trying to access the 'x' property of an instance of 'A'
// which does not exist
// so JavaScript looks for that property in the prototype object
// that was defined using the 'prototype' property of the constructor
In conclusion, in the first example a copy of the function is assigned to each instance. In the second example a single copy of the function is shared by all instances.
What's the difference? => A lot.
I think, the this version is used to enable encapsulation, i.e. data hiding.
It helps to manipulate private variables.
Let us look at the following example:
var AdultPerson = function() {
var age;
this.setAge = function(val) {
// some housekeeping
age = val >= 18 && val;
};
this.getAge = function() {
return age;
};
this.isValid = function() {
return !!age;
};
};
Now, the prototype structure can be applied as following:
Different adults have different ages, but all of the adults get the same rights.
So, we add it using prototype, rather than this.
AdultPerson.prototype.getRights = function() {
// Should be valid
return this.isValid() && ['Booze', 'Drive'];
};
Lets look at the implementation now.
var p1 = new AdultPerson;
p1.setAge(12); // ( age = false )
console.log(p1.getRights()); // false ( Kid alert! )
p1.setAge(19); // ( age = 19 )
console.log(p1.getRights()); // ['Booze', 'Drive'] ( Welcome AdultPerson )
var p2 = new AdultPerson;
p2.setAge(45);
console.log(p2.getRights()); // The same getRights() method, *** not a new copy of it ***
Hope this helps.
I know this has been answered to death but I'd like to show an actual example of speed differences.
Function directly on object:
function ExampleFn() {
this.print = function() {
console.log("Calling print! ");
}
}
var objects = [];
console.time('x');
for (let i = 0; i < 2000000; i++) {
objects.push(new ExampleFn());
}
console.timeEnd('x');
//x: 1151.960693359375ms
Function on prototype:
function ExampleFn() {
}
ExampleFn.prototype.print = function() {
console.log("Calling print!");
}
var objects = [];
console.time('y');
for (let i = 0; i < 2000000; i++) {
objects.push(new ExampleFn());
}
console.timeEnd('y');
//x: 617.866943359375ms
Here we're creating 2,000,000 new objects with a print method in Chrome. We're storing every object in an array. Putting print on the prototype takes about 1/2 as long.
Prototype is the template of the class; which applies to all future instances of it. Whereas this is the particular instance of the object.
Let me give you a more comprehensive answer that I learned during a JavaScript training course.
Most answers mentioned the difference already, i.e. when prototyping the function is shared with all (future) instances. Whereas declaring the function in the class will create a copy for each instance.
In general there is no right or wrong, it's more a matter of taste or a design decision depending on your requirements. The prototype however is the technique that is used to develop in an object oriented manner, as I hope you'll see at the end of this answer.
You showed two patterns in your question. I will try to explain two more and try to explain the differences if relevant. Feel free to edit/extend.
In all examples it is about a car object that has a location and can move.
Object Decorator pattern
Not sure if this pattern is still relevant nowadays, but it exists. And it is good to know about it.
You simply pass an object and a property to the decorator function. The decorator returns the object with property and method.
var carlike = function(obj, loc) {
obj.loc = loc;
obj.move = function() {
obj.loc++;
};
return obj;
};
var amy = carlike({}, 1);
amy.move();
var ben = carlike({}, 9);
ben.move();
Functional Classes
A function in JavaScript is a specialised object. In addition to being invoked, a function can store properties like any other object.
In this case Car is a function (also think object) that can be invoked as you are used to do. It has a property methods (which is an object with a move function). When Car is invoked the extend function is called, which does some magic, and extends the Car function (think object) with the methods defined within methods.
This example, though different, comes closest to the first example in the question.
var Car = function(loc) {
var obj = {loc: loc};
extend(obj, Car.methods);
return obj;
};
Car.methods = {
move : function() {
this.loc++;
}
};
var amy = Car(1);
amy.move();
var ben = Car(9);
ben.move();
Prototypal Classes
The first two patterns allow a discussion of using techniques to define shared methods or using methods that are defined inline in the body of the constructor. In both cases every instance has its own move function.
The prototypal pattern does not lend itself well to the same examination, because function sharing via a prototype delegation is the very goal for the prototypal pattern. As others pointed out, it is expected to have a better memory footprint.
However there is one point interesting to know:
Every prototype object has has a convenience property constructor, which points back to the function (think object) it came attached to.
Concerning the last three lines:
In this example Car links to the prototype object, which links via constructor to Car itself, i.e. Car.prototype.constructor is Car itself. This allows you to figure out which constructor function built a certain object.
amy.constructor's lookup fails and thus is delegated to Car.prototype, which does have the constructor property. And so amy.constructor is Car.
Furthermore, amy is an instanceof Car. The instanceof operator works by seeing if the right operand's prototype object (Car) can be found anywhere in the left operand's prototype (amy) chain.
var Car = function(loc) {
var obj = Object.create(Car.prototype);
obj.loc = loc;
return obj;
};
Car.prototype.move = function() {
this.loc++;
};
var amy = Car(1);
amy.move();
var ben = Car(9);
ben.move();
console.log(Car.prototype.constructor);
console.log(amy.constructor);
console.log(amy instanceof Car);
Some developers can be confused in the beginning. See below example:
var Dog = function() {
return {legs: 4, bark: alert};
};
var fido = Dog();
console.log(fido instanceof Dog);
The instanceof operator returns false, because Dog's prototype cannot be found anywhere in fido's prototype chain. fido is a simple object that is created with an object literal, i.e. it just delegates to Object.prototype.
Pseudoclassical patterns
This is really just another form of the prototypal pattern in simplified form and more familiar to do those who program in Java for example, since it uses the new constructor.
It does the same as in the prototypal pattern really, it is just syntactic sugar overtop of the prototypal pattern.
However, the primary difference is that there are optimizations implemented in JavaScript engines that only apply when using the pseudoclassical pattern. Think of the pseudoclassical pattern a probably faster version of the prototypal pattern; the object relations in both examples are the same.
var Car = function(loc) {
this.loc = loc;
};
Car.prototype.move = function() {
this.loc++;
};
var amy = new Car(1);
amy.move();
var ben = new Car(9);
ben.move();
Finally, it should not be too difficult to realize how object oriented programming can be done. There are two sections.
One section that defines common properties/methods in the prototype (chain).
And another section where you put the definitions that distinguish the objects from each other (loc variable in the examples).
This is what allows us to apply concepts like superclass or subclass in JavaScript.
Feel free to add or edit. Once more complete I could make this a community wiki maybe.
I believe that #Matthew Crumley is right. They are functionally, if not structurally, equivalent. If you use Firebug to look at the objects that are created using new, you can see that they are the same. However, my preference would be the following. I'm guessing that it just seems more like what I'm used to in C#/Java. That is, define the class, define the fields, constructor, and methods.
var A = function() {};
A.prototype = {
_instance_var: 0,
initialize: function(v) { this._instance_var = v; },
x: function() { alert(this._instance_var); }
};
EDIT Didn't mean to imply that the scope of the variable was private, I was just trying to illustrate how I define my classes in javascript. Variable name has been changed to reflect this.
As discussed in other answers, it's really a performance consideration because the function in the prototype is shared with all of the instantiations - rather than the function being created for each instantiation.
I put together a jsperf to show this. There is a dramatic difference in the time it takes to instantiate the class, although it is really only relevant if you are making many instances.
http://jsperf.com/functions-in-constructor-vs-prototype
Think about statically typed language, things on prototype are static and things on this are instance related.
When you use prototype, the function will only be loaded only once into memory (independently on the amount of objects you create) and you can override the function whenever you want.

Operator Overloading Javascript? (def.js) [duplicate]

Today I saw a JavaScript syntax (when invoking a function) that is unfamiliar to me. It was like:
def('Person') ({
init: function(name) {this.name=name;}
,speak: function(text) {alert(text || 'Hi, my name is ' + this.name);}
});
, and
def('Ninja') << Person ({
kick: function() {this.speak('I kick u!');}
});
1: What happens with the object within the parentheses in the first example? It is handled by the def function somehow, but I don't understand what is going on here (see the def function below). Where does the object go?
2: About the same thing again, but a use of the << operator that I never seen (I think!). What's that all about?
The code is from http://gist.github.com/474994, where Joe Dalton has made a small JavaScript-OO-inheritance thing (it is apparently a fork of someone else's work, but quite thoroughly rewritten, as it seems). Maybe you want to check it out there for the stuff referenced by the def function, which I give you here:
function def(klassName, context) {
context || (context = global);
// Create class on given context (defaults to global object)
var Klass =
context[klassName] = function Klass() {
// Called as a constructor
if (this != context) {
// Allow the init method to return a different class/object
return this.init && this.init.apply(this, arguments);
}
// Called as a method
// defer setup of superclass and plugins
deferred._super = Klass;
deferred._plugins = arguments[0] || { };
};
// Add static helper method
Klass.addPlugins = addPlugins;
// Called as function when not
// inheriting from a superclass
deferred = function(plugins) {
return Klass.addPlugins(plugins);
};
// valueOf is called to set up
// inheritance from a superclass
deferred.valueOf = function() {
var Superclass = deferred._super;
if (!Superclass)
return Klass;
Subclass.prototype = Superclass.prototype;
Klass.prototype = new Subclass;
Klass.superclass = Superclass;
Klass.prototype.constructor = Klass;
return Klass.addPlugins(deferred._plugins);
};
return deferred;
}
1: The call def('Person') returns a function, which is called with the object as parameter. It's the same principle as:
function x() {
return function(y) { alert(y); }
}
x()('Hello world!');
2: The << operator is the left shift operator. It shifts an integer value a specific number of bits to the left. I haven't found any reference for any other use for it, and there is no operator overloading in Javascript, so I can't make any sense out of using it on a function. So far it looks like a typo to me.
Edit:
As Tim explained, the shift operator is just used to induce a call to the valueOf method. It works like an overload of all operators, taking over the original purpose and doing something completely different.
Wow, it was convoluted enough for my tiny brain to understand, but I feel a lot better now knowing exactly how it works :) Thanks to #Tim for pointing out the valueOf() trick.
The general case of creating a "class" using:
def ("ClassName") ({
init: function() { .. },
foo: function() { .. }
});
is trivial, as the first call to def returns a function that accepts an object, and copies the properties of the passed in object, to the prototype of ClassName.
The more interesting case of using << to subclass relies on the evaluation order of the expression, as well as the attempted coercing of any object to a value by the implicit call to valueOf(). The underlying trick is basically a shared variable that records the super class and the properties to be applied to it. The expression,
def("ClassName") << ParentClass({ .. })
will be evaluated as follows:
def("ClassName") is called, and creates a global object ClassName and returns its constructor function. Let's call this returned object - initializeMeLater.
ParentClass(..) is called which stores the reference to ParentClass, and the passed in object/properties in a shared variable.
initializeMeLater.valueOf() is called, which gets the reference to the parent class, and the properties from that shared variable, and sets up the prototypes.
valueOf is called on the return value from step 2 which is useless and has no effect, as we have already setup the superclass relationship in step 3.
The code is trying to emulate Ruby syntax for creating subclasses which goes like:
class Child < Parent
def someMethod
...
end
end

Categories

Resources