Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why some people define the prototype property value of javascript object [closed]

Tags:

javascript

I have seen people doing the following way of coding lot of times but as I usually don't do it and it works fine with me without it, I am just curious on whether it is important or not. Note: I marked the lines I am talking about as // this line

function Test(name, something){
    this.name = name;
    this.something = something
}
Test.prototype.name = ''; // this line
Test.prototype.something = ''; // this line

Test.prototype.getName = function(){
    return this.name;
}
like image 615
cg.mike Avatar asked Mar 06 '14 23:03

cg.mike


2 Answers

There is a critical distinction here. To see the difference, instead of a string primitive, let's use an object:

Test.prototype.arr = [];

This will create an arr property on the Test prototype. Therefore, all instances of Test will share the exact same value of arr. To demonstrate, consider the following:

function Test(){}
Test.prototype.arr = [];

var t1 = new Test();
t1.arr.push("hello")
console.log(t1.arr); // ["hello"]

var t2 = new Test();
t2.arr.push("world")
console.log(t1.arr); // ["hello", "world"]
console.log(t2.arr); // ["hello", "world"]

See what happened there? The following lines

t1.arr.push("hello");
t2.arr.push("world");

change the value on the prototype itself. Thus all instances of Test, past and future, now have the arr property contain both strings.

Perhaps the above is what you originally intended; however, in most cases, what you want to do is actually set the property on the instance, and not the prototype:

function Test() {
    this.arr = [];
}
var t1 = new Test();
t1.arr.push("hello");
console.log(t1.arr); // ["hello"]

var t2 = new Test();
t2.arr.push("world");
console.log(t1.arr); // ["hello"],
console.log(t2.arr); // ["world"];

As for the example you provided, it may prove to be a little redundant and perhaps unnecessary to have the property first on the prototype, and then once an instance is created, an instance property.

Note that when the JavaScript runtime does a property look-up, the object itself is first checked, and if it doesn't have the property (checked by hasOwnProperty) its prototype is then checked; failing that, its prototype's prototype, until a match is found or the end of the prototype chain is reached (and a null value is returned).

Consider this:

function Test() {}
Test.prototype.name = "";

var t = new Test()
t.hasOwnProperty("name"); // false

name is only a property of the prototype, thus hasOwnProperty("name") will be false, while in the following case:

function Test(name) {
    this.name = name
}
Test.prototype.name = "";

var t = new Test();
t.hasOwnProperty("name"); // true

the creation of t causes a different name property to be created on the instance itself, thus hasOwnProperty("name") is now true.

like image 193
krisk Avatar answered Nov 14 '22 22:11

krisk


They probably just want to indicate that an instance of that class will have these properties. Since we know that properties on the prototype are shared by all instances, just by looking at the prototype we know which properties an instance will have. Everything is in "one place".
This might not be as obvious from the constructor function, which could be a lot more complicated which conditions and what not.

Additionally, some type checkers or documentation generation tools (like the Google Closure Compiler) might required to define any instance property on the prototype.

I am just curious on whether it is important or not

Regarding runtime behavior, no. The property assigned to the instance in the constructor will shadow the prototype property anyway.

like image 39
Felix Kling Avatar answered Nov 14 '22 21:11

Felix Kling