Reputation: 5934
Say I have a type called MyObject
and I want to add the method myMethod
to it. Is there any difference (logically, but also performance-wise) between the following ways?
#1
function MyObject() {
...
}
MyObject.prototype.myMethod = function() {
...
};
#2
function MyObject() {
this.myMethod = function() {
...
};
...
}
#3
function MyObject() {
this.myMethod = myMethod;
...
}
function myMethod() {
...
}
I wouldn't mind knowing if there's a performance difference - e.g. if way #2 is costly because it defines the function separately every time an object is instantiated - but I'm mostly concerned with whether the results are equivalent.
In addition, with method #2, isn't this the same way that a class-level/static method would be defined, so does it have the danger of being called like MyObject.myMethod();
? If myMethod
used this
and it was called on MyObject
rather than an instance of MyObject
, I would think this would cause issues. So does the compiler/interpreter check to see whether this
is present or would it throw an error?
Upvotes: 1
Views: 46
Reputation: 2411
Option 1: You can call my method without instantiating MyObject:
MyObject.prototype.myMethod();
Options 2: You must instantiate the MyObject to be able to access myMethod.
This will fail:
MyObject2.myMethod();
Uncaught TypeError: undefined is not a function
This will not:
var myObject = new MyObject2();
myObject.myMethod();
Check out the code pen: http://codepen.io/sessa/pen/tfqln
Upvotes: 2
Reputation: 32511
#1: This is the preferred way to write "class-level" methods. This saves on memory (as you'll see in #2) and JS engines can know that each instance will have this method and optimize around that.
#2: You're right, this one is more costly because it creates a new function for each instance. The difference here is that you can include private variables generated in the constructor. For example:
function MyObject() {
var name = 'Me';
this.getName = function() {
return name;
};
}
Only things created in the constructor will have access to name
.
#3: This approach is largely the same as #1 but I imagine that JavaScript engines are not written to optimize for this case (but this might not be true and may change, JS engines are constantly evolving). This also creates a global function (assuming you're not using a module system) which can create major issues later.
Upvotes: 2