Creating functions for an object in javascript - javascript

As far as I can tell, there are two main ways of creating functions for an object in javascript. They are:
Method A, make it in the constructor:
function MyObject() {
this.myFunc1 = function() {
...
}
this.myFunc2 = function() {
...
}
...
}
Method B, add it to the prototype:
function MyObject() {
...
}
MyObject.prototype.myFunc1 = function() {
...
}
MyObject.prototype.myFunc2 = function() {
....
}
Obviously if you did:
MyObject.myFunc3 = function() {
....
}
then myFunc3 would become associated with MyObject itself, and not any new objects created with the new keyword. For clarity, we'll call it method C, even though it doesn't work for creating new objects with the new keyword.
So, I would like to know what the differences between the two are. As far as I can tell they have the same effect logically, even if what's happening on the machine is different.
If I were to guess I would say that the only real difference is when you're defining them in the constructor like in method A, it creates a whole new function object for each object that's created, and Method B only keeps one copy of it (in MyObject), that it refers to any time it's called. if this is the case, why would you do it one way over the other. Otherwise, what is the difference between method A and method B.

The advantage of giving a separate function to each object is that you can close over variables in the constructor, essentially allowing for "private data".
function MyObject(a,b) {
var n = a + b; //private variable
this.myFunc1 = function() {
console.log(n);
}
};
vs
function MyObject(a,b) {
this.n = a + b; //public variable
}
MyObject.prototype.myFunc1 = function() {
console.log(this.n);
}
Whether this is a good idea or not depends on who you ask. My personal stance is reserving constructor functions for when I actually use the prototype, as in option #2 and using plain functions (say, make_my_object(a,b)) when using closures, as in option #1.

The idea is that you can modify the prototype at any time and all objects of the type (even those created before the modification) will inherit the changes. This is because, as you mentioned, the prototype is not copied with every new instance.

The MyObject in method A is an instance for inner functions.
You cannot call its functions explicitly outside of it unless object (you can call it a class) was instantiated.
Assume this:
MyObject.MyFunc1(); // will not work
var obj = new MyObject();
obj.MyFunc1(); // will work
so this is the same as any class in other languages. Describing usefulness of classes and their usages goes beyond that question though.
Also to notice:
function MyObject() {
var privateVar = "foo";
this.publicProperty = "bar";
// public function
this.publicFunc = function() {
...
}
// private function
function privateFunc () {
...
}
}
For method B it's same as with method A, the only difference is prototyping is a style of creating object. Some use prototypes for readability or out of preference.
The main advantage in prototypes is that you can extend existing object without touching the original source. You need to be careful with that though.
(as example Prototype framework)
For method C you can call them a static functions. As you said they can be called explicitly by referring through object like:
MyObject.MyFunc1();
So which one to use depends on situation you're handling.

Related

How can I pass 'this' object to lower function in javascript? [duplicate]

In C++, the language I'm most comfortable with, usually one declares an object like this:
class foo
{
public:
int bar;
int getBar() { return bar; }
}
Calling getBar() works fine (ignoring the fact that bar might be uninitialized). The variable bar within getBar() is in the scope of class foo, so I don't need to say this->bar unless I really need to make it clear that I'm referring to the class' bar instead of, say, a parameter.
Now, I'm trying to get started with OOP in Javascript. So, I look up how to define classes and try the same sort of thing:
function foo()
{
this.bar = 0;
this.getBar = function() { return bar; }
}
And it gives me bar is undefined. Changing the bar to this.bar fixes the issue, but doing that for every variable clutters up my code quite a bit. Is this necessary for every variable? Since I can't find any questions relating to this, it makes me feel like I'm doing something fundamentally wrong.
EDIT: Right, so, from the comments what I'm getting is that this.bar, a property of an object, references something different than bar, a local variable. Can someone say why exactly this is, in terms of scoping and objects, and if there's another way to define an object where this isn't necessary?
JavaScript has no classes class-based object model. It uses the mightier prototypical inheritance, which can mimic classes, but is not suited well for it. Everything is an object, and objects [can] inherit from other objects.
A constructor is just a function that assigns properties to newly created objects. The object (created by a call with the new keyword) can be referenced trough the this keyword (which is local to the function).
A method also is just a function which is called on an object - again with this pointing to the object. At least when that function is invoked as a property of the object, using a member operator (dot, brackets). This causes lots of confusion to newbies, because if you pass around that function (e.g. to an event listener) it is "detached" from the object it was accessed on.
Now where is the inheritance? Instances of a "class" inherit from the same prototype object. Methods are defined as function properties on that object (instead of one function for each instance), the instance on which you call them just inherits that property.
Example:
function Foo() {
this.bar = "foo"; // creating a property on the instance
}
Foo.prototype.foo = 0; // of course you also can define other values to inherit
Foo.prototype.getBar = function() {
// quite useless
return this.bar;
}
var foo = new Foo; // creates an object which inherits from Foo.prototype,
// applies the Foo constructor on it and assigns it to the var
foo.getBar(); // "foo" - the inherited function is applied on the object and
// returns its "bar" property
foo.bar; // "foo" - we could have done this easier.
foo[foo.bar]; // 0 - access the "foo" property, which is inherited
foo.foo = 1; // and now overwrite it by creating an own property of foo
foo[foo.getBar()]; // 1 - gets the overwritten property value. Notice that
(new Foo).foo; // is still 0
So, we did only use properties of that object and are happy with it. But all of them are "public", and can be overwritten/changed/deleted! If that doesn't matter you, you're lucky. You can indicate "privateness" of properties by prefixing their names with underscores, but that's only a hint to other developers and may not be obeyed (especially in error).
So, clever minds have found a solution that uses the constructor function as a closure, allowing the creating of private "attributes". Every execution of a javascript function creates a new variable environment for local variables, which may get garbage collected once the execution has finished. Every function that is declared inside that scope also has access to these variables, and as long as those functions could be called (e.g. by an event listener) the environment must persist. So, by exporting locally defined functions from your constructor you preserve that variable environment with local variables that can only be accessed by these functions.
Let's see it in action:
function Foo() {
var bar = "foo"; // a local variable
this.getBar = function getter() {
return bar; // accesses the local variable
}; // the assignment to a property makes it available to outside
}
var foo = new Foo; // an object with one method, inheriting from a [currently] empty prototype
foo.getBar(); // "foo" - receives us the value of the "bar" variable in the constructor
This getter function, which is defined inside the constructor, is now called a "privileged method" as it has access to the "private" (local) "attributes" (variables). The value of bar will never change. You also could declare a setter function for it, of course, and with that you might add some validation etc.
Notice that the methods on the prototype object do not have access to the local variables of the constructor, yet they might use the privileged methods. Let's add one:
Foo.prototype.getFooBar = function() {
return this.getBar() + "bar"; // access the "getBar" function on "this" instance
}
// the inheritance is dynamic, so we can use it on our existing foo object
foo.getFooBar(); // "foobar" - concatenated the "bar" value with a custom suffix
So, you can combine both approaches. Notice that the privileged methods need more memory, as you create distinct function objects with different scope chains (yet the same code). If you are going to create incredibly huge amounts of instances, you should define methods only on the prototype.
It gets even a little more complicated when you are setting up inheritance from one "class" to another - basically you have to make the child prototype object inherit from the parent one, and apply the parent constructor on child instances to create the "private attributes". Have a look at Correct javascript inheritance, Private variables in inherited prototypes, Define Private field Members and Inheritance in JAVASCRIPT module pattern and How to implement inheritance in JS Revealing prototype pattern?
Explicitly saying this.foo means (as you've understood well) that you're interested about the property foo of the current object referenced by this. So if you use: this.foo = 'bar'; you're going to set the property foo of the current object referenced by this equals to bar.
The this keyword in JavaScript doesn't always mean the same thing like in C++. Here I can give you an example:
function Person(name) {
this.name = name;
console.log(this); //Developer {language: "js", name: "foo"} if called by Developer
}
function Developer(name, language) {
this.language = language;
Person.call(this, name);
}
var dev = new Developer('foo', 'js');
In the example above we're calling the function Person with the context of the function Developer so this is referencing to the object which will be created by Developer. As you might see from the console.log result this is comes from Developer. With the first argument of the method call we specify the context with which the function will be called.
If you don't use this simply the property you've created will be a local variable. As you might know JavaScript have functional scope so that's why the variable will be local, visible only for the function where it's declared (and of course all it's child functions which are declared inside the parent). Here is an example:
function foo() {
var bar = 'foobar';
this.getBar = function () {
return bar;
}
}
var f = new foo();
console.log(f.getBar()); //'foobar'
This is true when you use the var keyword. This means that you're defining bar as local variable if you forget var unfortunately bar will became global.
function foo() {
bar = 'foobar';
this.getBar = function () {
return bar;
}
}
var f = new foo();
console.log(window.bar); //'foobar'
Exactly the local scope can help you to achieve privacy and encapsulation which are one of the greatest benefits of OOP.
Real world example:
function ShoppingCart() {
var items = [];
this.getPrice = function () {
var total = 0;
for (var i = 0; i < items.length; i += 1) {
total += items[i].price;
}
return total;
}
this.addItem = function (item) {
items.push(item);
}
this.checkOut = function () {
var serializedItems = JSON.strigify(items);
//send request to the server...
}
}
var cart = new ShoppingCart();
cart.addItem({ price: 10, type: 'T-shirt' });
cart.addItem({ price: 20, type: 'Pants' });
console.log(cart.getPrice()); //30
One more example of the benefits of the JavaScript scope is the Module Pattern.
In Module Pattern you can simulate privacy using the local functional scope of JavaScript. With this approach you can have both private properties and methods. Here is an example:
var module = (function {
var privateProperty = 42;
function privateMethod() {
console.log('I\'m private');
}
return {
publicMethod: function () {
console.log('I\'m public!');
console.log('I\'ll call a private method!');
privateMethod();
},
publicProperty: 1.68,
getPrivateProperty: function () {
return privateProperty;
},
usePublicProperty: function () {
console.log('I\'ll get a public property...' + this.publicProperty);
}
}
}());
module.privateMethod(); //TypeError
module.publicProperty(); //1.68
module.usePublicProperty(); //I'll get a public property...1.68
module.getPrivateProperty(); //42
module.publicMethod();
/*
* I'm public!
* I'll call a private method!
* I'm private
*/
There's a little strange syntax with the parentless wrapping the anonymous functions but forget it for the moment (it's just executing the function after it's being initialized). The functionality can be saw from the example of usage but the benefits are connected mainly of providing a simple public interface which does not engages you with all implementation details. For more detailed explanation of the pattern you can see the link I've put above.
I hope that with this :-) information I helped you to understand few basic topics of JavaScript.
function Foo() {
this.bar = 0;
this.getBar = function () { return this.bar };
}
When you call the function above with the new keyword - like this...
var foo = new Foo();
... - a few things happen:
1) an object is created
2) the function is executed with the this keyword referencing that object.
3) that object is returned.
foo, then, becomes this object:
{
bar: 0,
getBar: function () { return this.bar; }
};
Why not, then, just do this:
var foo = {
bar: 0,
getBar: function () { return this.bar; }
};
You would, if it's just that one simple object.
But creating an object with a constructor (that's how it's called) gives us a big advantage in creating multiple of the "same" objects.
See, in javascript, all functions are created with a prototype property [an object], and all objects created with that function (by calling it with the new keyword) are linked to that prototype object. This is why it's so cool - you can store all common methods (and properties, if you wanted to) in the prototype object, and save a lot of memory. This is how it works:
function Foo( bar, bob ) {
this.bar = bar;
this.bob = bob;
}
Foo.prototype.calculate = function () {
// 'this' points not to the 'prototype' object
// as you could've expect, but to the objects
// created by calling Foo with the new keyword.
// This is what makes it work.
return this.bar - this.bob;
};
var foo1 = new Foo(9, 5);
var foo2 = new Foo(13, 3);
var result1 = foo1.calculate();
var result2 = foo2.calculate();
console.log(result1); //logs 4
console.log(result2); //logs 10
That's it!
To get closer to OOP in JavaScript, you might want to take a look into a Module design pattern (for instance, described here).
Based on the closure effect, this pattern allows emulating private properties in your objects.
With 'private' properties you can reference them directly by its identifier (i.e., no this keyword as in constructors).
But anyway, closures and design patterns in JS - an advanced topic. So, get familiar with basics (also explained in the book mentioned before).
In javascript this always refers to the owner object of the function. For example, if you define your function foo() in a page, then owner is the javascript object windows; or if you define the foo() on html element <body>, then the owner is the html element body; and likewise if you define the function onclick of element <a>, then the owner is the anchor.
In your case, you are assigning a property bar to the 'owner' object at the begining and trying to return the local variable bar.
Since you never defined any local varialbe bar, it is giving you as bar is undefined.
Ideally your code should have defined the variable as var bar; if you want to return the value zero.
this is like a public access modifier of objects(variables or functions), while var is the private access modifier
Example
var x = {};
x.hello = function(){
var k = 'Hello World';
this.m = 'Hello JavaScript';
}
var t = new x.hello();
console.log(t.k); //undefined
console.log(t.m); //Hello JavaScript

Differences between "this" in JavaScript and ActionScript

My background is heavy in JavaScript. I have a very advanced understanding of both ES5 and ES6. At work I was recently assigned a project involving an older flash application, which uses AS2. It is my understanding that ActionScript is very similar to ES5, but with classes and optional strict typing (akin to TypeScript and Flow), as well as a few other classic OO features. It is fairly straightforward so far, but I'm having trouble understanding how this and references work in ActionScript.
This is my understanding for JavaScript. this in a function can reference:
A bound variable, if using Function.bind() (as well as Function.call() and Function.apply()), which cannot be changed in the bound function, for example:
function func() {
return this.number;
}
var bound = func.bind({ number: 2 });
console.log(bound()); // 2
An object, if the function is called as a method on that object, for example:
function func() {
return this.number;
}
var obj = { number: 2, func: func };
console.log(obj.func()); // 2
An instance of a class, if that function is defined on the prototype of that class, for example:
function Class() {
this.number = 2;
}
Class.prototype.func = function func() {
return this.number;
}
console.log(new Class().func()); // 2
The global object, if the function is called without any kind of binding or object or instance attached to it, for example:
var number = 2;
function func() {
return this.number;
}
console.log(func()); // 2
In ActionScript things seem to be a bit different. For one thing, you can access class members without this if you are doing it within a method of that class, similar to languages like C# and Java:
class MyClass {
private var number:Number = 2;
public function func():Number {
return number;
}
}
trace(new MyClass().func()); // 2
Also, the ActionScript standard library doesn't seem to have a Function.bind() method, though it does have Function.apply() and Function.call() which seem to work just like the JavaScript variations: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/2/help.html?content=00001072.html#265677. There also don't seem to be prototypes, which makes sense because classes are more abstract syntactic structures rather than functions (just like C#/Java) based on my understanding.
So my question is, excluding the lack of Function.bind() and Function.prototype, are the rules the same between ActionScript and JavaScript?
In addition, what happens if I do this:
class SomeClip extends MovieClip {
private var childClip:MovieClip;
private var number:Number = 2;
public function SomeClip() {
this.onLoad = function() {
// SomeClip onLoad hander, `this` will be the SomeClip instance
childClip._visible = true; // How is childClip resolved here?
childClip.onRelease = function() {
// childClip onRelease handler, `this` will be childClip
trace(number); // How is number resolved here?
};
};
}
}
Basically, if you access a member without this in an event handler, or some other loose function that is not a method of the class, what happens? I would guess that in the first case, it would resolve to this.childClip and work as one would expect, but in the second case, the resolution would fail because the onRelease handler's closure won't contain a reference to the SomeClip instance.
I see the comments that have been written so far are more focused on JS, so I'll try my best to answer from an ActionScript perspective.
In the world of AS2/AS3, functions that are defined as methods on a class have their this value bound to the class. This is typical of many higher-level languages with modern classes, such as Java, Haxe, etc. As such, in ActionScript you'll rarely find the need to use the this keyword other than cases where a variable name might be shadowed by a function argument:
public function Point(x:Number = 0, y:Number = 0)
{
// A rare but necessary use-case of "this" in AS2/AS3
this.x = x;
this.y = y;
}
On the other hand, if the function you provide is anonymous as in the example you wrote, the behavior depends on whether or not you prepend this:
childClip.onRelease = function() {
trace(number);
};
In this case ActionScript is able to determine number is a member of the class, and will print 2 like you expected since. This is because the interpreter looks for the next closest thing in the stack. In other words, you were ambiguous by excluding this so it knows it needs to perform a lookup.
However if you were to trace(this.number) instead, you would find that you get an undefined (and possibly even an error). This is because this is not a member variable on the class, and now points to a "global object" similar to JS. To avoid dancing with the global object, it's common practice for ActionScript developers to define all of their listeners as class instance methods:
class MyClass extends EventDispatcher
{
private function MyClass()
{
addEventListener(Event.CHANGE, onChangeEvent);
}
private function onChangeEvent(e:Event) {
trace(this); // refers to this class, and no need for bind() like JS
}
}
Well organized AS3 code will almost never contain inline anonymous functions, since it's much easier to handle garbage collection by using explicit function references.
One last thing to note - you can expect functions that are methods of regular Objects in ActionScript to behave like JavaScript where passing them around via event listeners will result in the context of this being lost, and Flash will not do the magic lookup to locate the variable you referenced:
var obj = {
func: function () {
trace(this); // weird global object
}
};
addEventListener(Event.CHANGE, obj.func);
Hope that helps!
In AS2 functions are not bound and get "this" reference passed (evidently via Function.apply or by the object reference) in the moment of call:
function getIndex()
{
trace(this.index);
}
var A = {index:1, getIndex:getIndex};
var B = {index:2, getIndex:getIndex};
A.getIndex(); // 1
B.getIndex(); // 2
B.getIndex.apply(A); // 1
Binding methods to certain objects was called "delegating": http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00001842.html#1001423 In a nutshell, functions are objects too and you can create special function object that has references to both method to call and "this" object to pass:
function getIndex()
{
trace(this.index);
}
function bind(method, target):Function
{
var result:Function = function()
{
// arguments.callee is always a reference
// to the current function object
arguments.callee.method.apply(arguments.callee.target);
}
result.method = method;
result.target = target;
return result;
}
var A = {index:1};
var B = {index:2};
A.getIndex = bind(getIndex, A);
B.getIndex = bind(getIndex, B);
A.getIndex(); // 1
B.getIndex(); // 2
B.getIndex.apply(A); // 2
Then, if you don't use "this" reference, once you address some variable by its name there are several contexts that are searched for such a variable in order:
local function variables
local wrapper function variables (this one is truly horrible for no one really knows where these variables exist and it is a potent memory leak)
MovieClip, that holds the function code, local variables
global variables
Play with the following code, comment some "index" variables and you'll see it:
// Global variable.
_global.index = 6;
// MovieClip local variable.
var index = 5;
function wrap():Function
{
// Wrapper function local variable.
var index = 4;
return function()
{
// Function local variable.
var index = 3;
trace(index);
}
}
wrap()();

Get the object that calls a function belonging to one of its properties OR namespacing prototypes?

(Obviously I'm not sure what the title of this should be.)
I'd like to be able to modify the prototypes of native objects with minimal risk (because trust me; I have heard over and over again how it's a mortal javascript sin).
My train of thought goes something like this: I can greatly reduce the possibility of conflicts if I can add my custom functions to a single object on a prototype rather than directly adding them to the prototype itself.
If I have the code,
String.prototype.foo = function() {
//do stuff
};
...obviously the keyword this references the string that called it. However, if I do something like,
String.prototype.foo = {};
String.prototype.foo.bar = function() {
//do stuff
};
...the keyword this references the object foo.
If there some way to overcome this?
The only way to overcome this would be to override the context using call:
String.prototype.foo.bar.call('hello'))
which works, but is pretty ridiculous.
You're better off (as you've already heard) avoiding modifying native prototypes, and instead having an object with your methods accepting the string as a parameter.
Well, there's a couple of ways to do this, depending on how much work you want to put in.
Using bind is the most straightforward way, but you have to define the string as a variable so you can pass a reference of it to bind:
String.prototype.foo = function() { console.log(this); }
String.prototype.foo.bar = function() { console.log(this); }
var g = "hi there";
g.foo() // Yields g
g.foo.bar() // Yields String.prototype.foo()
g.foo.bar.bind(g)() // Yields g again.
There may be another very hackish way to produce the desired result by creating getters and setters on String.prototype.foo so that String.prototype.foo.bar activates a function that returns a function bound to the instance that foo refers to. ??? Confusing.
What might be the best solution to reduce the possibility of conflicts, is to take advantage of prototypal inheritance and create your own sub prototype of the native String.
function MyString(string) {
this.foo = function() { //whatever };
this.foo.bar = (function() {}).bind(this);
this.toString = function() { return string; } // because toString is not generic.
}
MyString.prototype = new String();
Here, you're creating your own "sub-prototype" of the String prototype. It inherits all the properties of the String prototype and adds its own, all without altering the native strings at all. BONUS: this.foo and this.foo.bar will both refer to your instance.
var instance = new MyString("hi");
instance.foo(); // this == instance
instance.foo.bar(); // this == instance
instance.replace("i", "e"); // returns "he"
This maybe wasn't the answer you were looking for, but hopefully it will at least be helpful.

How do I inherit a function from a base object and overwrite it in javascript

What I am trying to do is have a child object provide its own implementation for a function defined in a base object. As far as I've understood so far prototypes are the best (only!) way to go about doing this.
Note also that I am currently developing using the game engine: Turbulenz and as such I am trying to follow / stick to their style as closely as possible. In the engine "classes"/objects are defined and created in the following manner
function baseObject() { }
baseObject.prototype =
{
myMember1: 1,
myMember2: 2,
myMethod: function myMethodFn() {
return this.myMember1 + this.myMember2;
}
}
baseObject.Create = function baseObjectCreateFn
{
var o = new baseObject();
return o;
}
This would allow me to do the following
var anObject = baseObject.Create();
var someValue = anObject.myMethod(); // should return 3
What I would like to be able to do now is to create a new object that inherits all the properties of baseObject while allowing me to overwrite its myMethod function to for example subtract the two member values instead of add.
Would I be correct in saying that I will have to create another object then alter its prototype? The part thats throwing me most is that the definition of the baseObject's prototype is defined as an object literal and so I'm unsure of the syntax to overwrite one of its members, i.e. would the following be valid or not? :
function childObject() {}
childObject.prototype = baseObject.Create() // would this inherit from baseObject?
// or should it be: childObject.prototype = new baseObject();
// this is the part thats confusing me as the syntax
// doesn't quite match the original base objects prototype
// syntax and I'm unsure if that will matter
childObject.prototype.myMethod = function myMethodFn() {
return this.myMember1 - this.myMember2;
}
childObject.Create = function childObjectCreateFn
{
var o = new childObject();
return o;
}
var aChildObject = childObject.Create()
var anotherValue = aChildObject.myMethod() // would this return -1 as expected?
To summarise I'm trying to create an object that will overwrite a function that exists in a base object by inheriting the function from the base object and changing it, how do I do this? Thanks for your time.
You have it correct.
As for the syntax confusion, there is no real difference between
thing.prototype.myMethod = function () { ... }
and
thing.prototype = { myMethod: function() { ... } };
except for the fact that in the second one you are setting the prototype all at once (to an object literal), and if you do it again, you'll overwrite the prototype all at once with a new object literal. But because it is an object literal, you can't do inheritance this way (everything declared with naked braces { ... } is just an instance of Object of no special type). If you stick with the first syntax you'll always be ok.
Note that when you put:
childObject.prototype.myMethod = function myMethodFn() { ... }
The part where you put myMethodFn is actually ignored. The function is named myMethod by the fact that this is where you assigned it.
Similarly, where you have
childObject.Create = function childObjectCreateFn
you don't need childObjectCreateFn (it's ignored), and you need to put parentheses () somewhere after function or it's a syntax error.
Moving on to the reason why this works, every created object in Javascript has a prototype. When you call a method on that object, it first looks inside the object itself to see if a key corresponding to the name of the method exists. If not, it looks in the prototype object for the same thing, and if it's not there, it goes to that object's prototype, and so on, until it gets to the root Object, which has no prototype.
In this way you can override an implementation merely by naming it the same thing, but having it appear earlier in the prototype chain. That's exactly what you're doing on childObject. It retains the functionality of baseObject because you created an instance of baseObject to serve as childObject's prototype. Then you augmented childObject's prototype with a new method of the same name, but one that comes earlier in the prototype chain.

What's the recommended way to declare fields of a class in JavaScript?

Is it better to declare fields of a class in this way:
function MyClass() {
this.aMethod = function() {
// code
}
}
Or this way:
function MyClass() {
}
MyClass.prototype.aMethod = function() {
// code
}
Any why?
Thanks in advance.
The prototypal method, because it's more efficient as it adds the function to the prototype meaning any objects created with the constructor automatically get that method, while the former/first way those methods have to be created for each and every little object you make individually.
Though really it depends on what you're doing with the method. If you don't need it to be a public method then you may opt with this.method or a function statement.
As #meder said, the prototypal approach is the preferred way, since the the methods are declared in the constructor's prototype, but the first approach you show us is useful to implement private members, for example:
function MyClass() {
var privateValue = 'secret';
function privateMethod() { }
this.aMethod = function() {
// privateValue and privateMethod are accessible here.
return privateValue;
}
}
var foo = new MyClass();
foo.aMethod(); // "secret"
foo.privateValue; // undefined !
That's what Crockford calls a privileged method, because this method has access to all the identifiers created in the lexical scope of the constructor (a closure is created).
It depends on the usage. Use the first method when you are going to use the method frequently; the second, when you are going to make rare use of it. The reason is that when the object is created with the constructor, prototypal methods are not loaded, they are only loaded when called, which will save you some performance.

Categories

Resources