4

What is the difference between this two codes and which one should I use?

function Test() {}
Test.method = function() {};

With Prototype:

function Test() {}
Test.prototype.method = function() {};
and-k
  • 537
  • 1
  • 8
  • 16

6 Answers6

5

1st case : static method.

function Test() {}
Test.method = function () { alert(1); };
var t = new Test;
Test.method(); // alerts "1"
t.method(); // TypeError: Object #<Test> has no method 'method'

2nd case : instance method.

function Test() {}
Test.prototype.method = function () { alert(1); };
var t1 = new Test;
var t2 = new Test;
t1.method(); // alerts "1"
t2.method(); // alerts "1"
Test.method(); // TypeError: Object function Test() {} has no method 'method'
  • 1
    I don't care for it. A static method in Java is a special thing. It is marked by a keyword. The runtime knows to do something with it. There is no such thing in JavaScript. This is just a property on an object. There is nothing special about it. – Wayne Feb 12 '14 at 19:59
  • I was responding to another comment, but it seems to have been deleted. – Wayne Feb 12 '14 at 19:59
  • 1
    @lwburk I agree, it's worth noting that "You might call this a static method, [...] but it's really just a normal property." : http://stackoverflow.com/a/21738059/1636522. –  Feb 12 '14 at 20:02
1

The first example merely assigns a function to a new property of Test called method. There is nothing special or magic about it (by which I mean, the language does not do anything interesting with it). You might call this a static method, because it's shared across all instances, but it's really just a normal property. (Functions are objects and objects have properties.)

In the second case, a new method is added to Test's prototype, which makes it available to all instances of Test. This is special behavior. Every object in JavaScript has an internal link to another object, which is called its prototype. This link is established using the prototype of the constructor that created the object, so any instance created by Test will have the new property in its prototype chain.

For example:

function Test() {}
Test.method = function() {};

var a = new Test();
console.log(a.method); // => undefined

But:

function Test() {} 
Test.prototype.method = function() {};

var a = new Test();
console.log(a.method); // => function
Wayne
  • 59,728
  • 15
  • 131
  • 126
0

The prototype method is shared between all instances of Test.

Sterling Archer
  • 22,070
  • 18
  • 81
  • 118
0

Will NOT Work (for an instance)

function Test() {}
Test.method = function() {};

Will Work (for an instance)

function Test() {}
Test.prototype.method = function() {};

Why?

Assuming that you create an instance of Test:

t = new Test()

On calling a method:

t.method()

JavaScript will first look within Test, for example the 3 properties and methods will be recognized below:

function Test() {} {

    this.a = "hello";
    this.b = "world";
    this.c = function() { alert( this.a + this.b) }

}

and then the second, the look up will be done on prototype:

Test.prototype.method = function() { console.log('prototype defined method') }

In JavaScript the below does not register to the instance t but instead Test:

Test.method = function() { console.log('something unsual') };

therefore

Test.method()  // works
t.method()     // no works
Raj Nathani
  • 2,805
  • 1
  • 20
  • 19
0

The difference goes back to how the prototype chaining works. If you create instances of Test then they will be able to access the methods that are defined on the prototype.

The first code, simply adds a "static" method on the constructor; You won't be able to access that method doing something like this:

var testInst = new Test();
testInst.method() // Error Undefined is not a function

The only way to invoke that method is via the constructor reference i.e.

Test.method();

As i mentioned, the above is feasible if you add the method to the prototype of the constructor.

ppoliani
  • 4,792
  • 3
  • 34
  • 62
0

If you define a method in the prototype, any instances will be able to use that method. If you define the method as simply a part of the original object, it allows you to simply use that in a manner that one could reasonably refer to as a static method.

For example:

Array.isArray( [] )  //true

[].isArray() //throws a TypeError

The second example throws a TypeError because isArray() is not in the Array.prototype (remember, instances only access methods defined in that instance, or in that instance's prototype or __proto__ chain).

In short:
* A method defined in the original object can be accessed by that object, but not instances of that object.
* A method defined in the original object's prototype can be accessed by any instance of the original object.

Josh Beam
  • 19,292
  • 3
  • 45
  • 68