Own Properties versus prototype Properties

In the example above getInfo() used this internally to address the object. Using Gadget.prototype we could achieve the same result:

Gadget.prototype.getInfo = function() {
    return 'Rating: ' + Gadget.prototype.rating + ', price: ' + Gadget.prototype.price;
};

How the prototype works?

In newtoy object, when you try to access a property(newtoy.name) of newtoy the JavaScript engine will look through all of the properties of the object and, if it finds it, will return its value.

var newtoy = new Gadget('webcam', 'black');
newtoy.name
"webcam"

In newtoy object, when you try to access the rating property the JavaScript engine will examine all of the properties of newtoy and will not find the one called rating. Then the script engine will identify the prototype of the constructor function used to create this object (same as if you do newtoy.constructor.prototype). If the property is found in the prototype, this property is used.

newtoy.rating

3

It would be the same as if we access the prototype directly. Every object has a constructor property, which is a reference to the function that created the object.

newtoy.constructor
Gadget(name, color)

newtoy.constructor.prototype.rating
3

Every object has a constructor. The prototype is an object, so it must have a constructor too, which in turn has a prototype.

newtoy.constructor.prototype.constructor
Gadget(name, color)

newtoy.constructor.prototype.constructor.prototype
Object price=100 rating=3

This might go on for a while, depending on how long the prototype chain is, but eventually end up with the built-in Object() object, which is the highest-level parent. When you use newtoy.toString(), the newtoy and its prototype doesn't have an own toString(),so we get the Object's toString().

newtoy.toString()

"[object Object]"

Enumerating Properties ......................

If you want to list all properties of an object, you can use a for-in loop. In Chapter 2, you saw how you could loop through all the elements of an array:

var a = [1, 2, 3];
for (var i in a) {
    console.log(a[i]);
}

Arrays are objects, so you can expect that the for-in loop works for objects too:

snippet
var o = {
    p1: 1,
    p2: 2
};

for (var i in o) {
    console.log(i + '=' + o[i]);
}

This produces:

p1=1
p2=2

There are some details to be aware of:

Not all properties show up in a for-in loop. For example, the length (for arrays) and constructor properties will not show up. The properties that do show up are called enumerable. You can check which ones are enumerable with the help of the propertyIsEnumerable() method that every object provides.

Prototypes that come through the prototype chain will also show up, provided they are enumerable. You can check if a property is an own property versus prototype's using the

  • hasOwnProperty() method.
  • propertyIsEnumerable() will return false for all of the prototype's properties, even those that are enumerable and will show up in the for-in loop.

Let's see these methods in action. Take this simplified version of Gadget():

snippet
function Gadget(name, color) {
    this.name = name;
    this.color = color;
    this.someMethod = function() {
        return 1;
    }
}
Gadget.prototype.price = 100;
Gadget.prototype.rating = 3; &
bull; &
bull; &
bull; < /p> <
p >
Creating a new object:
var newtoy = new Gadget('webcam', 'black');

Now if you loop using a for-in, you see of the object's all properties, including those that come from the prototype:

for (var prop in newtoy) {
    console.log(prop + ' = ' + newtoy[prop]);
}

The result also contains the object's methods (as methods are just properties that happen to be functions):

snippet
name = webcam
color = black
someMethod = function() {
    return 1;
}
price = 100
rating = 3

If you want to distinguish between the object's own properties versus the prototype's properties, use hasOwnProperty(). Try first:

newtoy.hasOwnProperty('name')
true

newtoy.hasOwnProperty('price')
false

Let's loop again, but showing only own properties:

for (var prop in newtoy) {
    if (newtoy.hasOwnProperty(prop)) {
        console.log(prop + '=' + newtoy[prop]);
    }
}

The result:

name=webcam
color=black
someMethod=function () { return 1; }

Now let's try propertyIsEnumerable(). This method returns true for own properties that are not built-in:

newtoy.propertyIsEnumerable('name')
true

Most built-in properties and methods are not enumerable:

newtoy.propertyIsEnumerable('constructor')
false

Any properties coming down the prototype chain are not enumerable:

newtoy.propertyIsEnumerable('price')
false

Note, however, that such properties are enumerable if you reach the object contained in the prototype and invoke its propertyIsEnumerable().

newtoy.constructor.prototype.propertyIsEnumerable('price')
true
Related Tutorial
Follow Us
https://www.facebook.com/Rookie-Nerd-638990322793530 https://twitter.com/RookieNerdTutor https://plus.google.com/b/117136517396468545840 #
Contents