Difference between adding function to prototype and object literal in javascript
Asked Answered
B

3

26

If I have a constructor Quo

var Quo = function (string) {
     this.status = string;
};

and then made a new object using var myQuo = new Quo("confused");

what would be the difference between:

Quo.get_status = function () { 
    return this.status;
};

and

Quo.prototype.get_status = function () { 
    return this.status;
};
Bis answered 21/12, 2013 at 23:12 Comment(1)
This answer may help you out understanding constructor functions and prototype: https://mcmap.net/q/24597/-prototypical-inheritance-writing-up-duplicatePoisonous
A
26

Let's suppose you have created myQuo, as you described

var myQuo = new Quo("confused");

If you define get_status as a property of Quo, then to get the status of myQuo you would have to call Quo.get_status. However, Quo.get_status will need to know the object context (myQuo) to return the correct value of status. You can redefine the function to accept the object as an argument as in the following:

Quo.get_status = function (quo) { 
  return quo.status;
};
var status = Quo.get_status(myQuo);

Alternatively, you could keep the function Quo.get_status as you wrote it in your question, but you will need to invoke the function in a manner that binds myQuo to "this":

Quo.get_status = function() {
  return this.status;
};
var status = Quo.get_status.call(myQuo);

Either solution is awkward. The preferred solution is to take advantage of Javascript's prototype functionality and define get_status as a prototype function that will be locally accessible to all Quo objects, such as myQuo.

Quo.prototype.get_status = function () { 
  return this.status;
};
var status = myQuo.get_status();
Attaint answered 21/12, 2013 at 23:18 Comment(3)
This makes sense, my only confusion is when you call Quo.get_status(myQuo);. How can you pass in a argument myQuo if the function takes no parameters? Is this a mistake?Bis
@oroscioli You can't actually, thanks for pointing that out, since I accidentally skimmed over that detail. I have edited my answer accordingly.Attaint
It seems the difference between static method and instance method in JavaSubtrahend
P
22

When you define a function, it has a property prototype that is used as the [[prototype]] of all of the objects it creates using the new keyword. When you add members to Quo.prototype, all objects created using new Quo() will be able to read the member as if they had it (through their [[prototype]], namely Quo.prototype). On the other hand, if you assign members to Quo directly, you can only access them through Quo itself.

Example:

var Quo = function (status) {
    this.status = status;
}

Quo.status = "enlightened";

Quo.get_status = function() {
    return this.status;
}

Quo.prototype.get_status = function() {
    return this.status;
}

var quo = new Quo("confused");

Quo.get_status(); // "enlightened"
quo.get_status(); // "confused"
Pydna answered 21/12, 2013 at 23:18 Comment(0)
F
0

Functions that require knowledge of the instance (the created object) should be added to the 'class' prototype, the prototype function assigned to the constructor function.

If you do

instance = new Class();

then any function foo you added to the prototype of Class can be invoked as

instance.foo()

and will have access to all instance variables of instance through the this pointer.

Functions added to the constructor function Class are just members of the function object named as Class and do not know of nor care for instances you might have created.

Usually, you add constants to the constructor functions. So if you create a class 'Color' and add it Color.BLACK = 0; (or better Object.defineProperty(Color, 'BLACK', { value: 0}); ) to make it immutable, yo can access it like Color.BLACK.

It still can be useful to add functions to the constructor function. Doing so is like defining static functions in a Java class. There are mainly three types of functions that should be placed at the constructor:

  1. generic (helper) functions that do not need an instance, e.g. Number.isFinite()

  2. Conversion functions like Color.compare(color1, color2). They allow working without an instance. However, they might internally create an instance and may use instance functions from the prototype.

Color.compare(color1, color2) {
    var color1 = new Color(color1);
    return color1.compare(color2);
}
  1. specific constructor functions. While it is possible to deliberately interpret the parameters passed to the constructor and determine what they might mean, it could be way more convenient, to have separate functions that create and return an instance based on different parameters:
Color.RGB = function (r, g, b) {
    var instance = new Color();  
    instance.r = r;  
    instance.g = g;  
    instance.b = b;  
    instance.RGBtoYCC();  
    return instance;  
}  
Color.YCC = function (Y, Cr, Cb) {  
    var instance = new Color();  
    instance.Y = Y;  
    instance.Cr = Cr;  
    instance.Cb = Cb;
    instance.CYYtoRGB();  
    return instance;  
}

So you can create a 'red' color as either

var color = Color.RGB(255,0,0);

or as

var color = Color.YCC(0.29889978, 0.5, -0.1687);
Forgiveness answered 19/4 at 14:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.