javascript tutorial - [Solved-5 Solutions] Prototype - javascript - java script - javascript array



Problem:

I'm not that into dynamic programming languages, but I've written my fair share of JavaScript code. We never really got my head around this prototype-based programming, does any one know how this works?

var obj = new Object(); // not a functional object
obj.prototype.test = function() { alert('Hello?'); }; // this is wrong!

function MyObject() {} // a first class functional object
MyObject.prototype.test = function() { alert('OK'); } // OK
click below button to copy the code. By JavaScript tutorial team

Solution 1:

Every JavaScript object has an internal property called [[Prototype]]. If we look up a property via obj.propName or obj['propName'] and the object does not have such a property - which can be checked via obj.hasOwnProperty('propName') - the runtime looks up the property in the object referenced by [[Prototype]] instead. If the prototype-object also doesn't have such a property, its prototype is checked in turn, thus walking the original object's prototype-chain until a match is found or its end is reached.

Some JavaScript implementations allow direct access to the [[Prototype]] property, eg via a non-standard property named __proto__. In general, it's only possible to set an object's prototype during object creation: If we create a new object via new Func(), the object's [[Prototype]] property will be set to the object referenced by Func.prototype.

This allows to simulate classes in JavaScript, although JavaScript's inheritance system is - as we have seen - prototypical, and not class-based:

Just think of constructor functions as classes and the properties of the prototype (ie of the object referenced by the constructor function's prototype property) as shared members, ie members which are the same for each instance. In class-based systems, methods are implemented the same way for each instance, so methods are normally added to the prototype, whereas an object's fields are instance-specific and therefore added to the object itself during construction.

Solution 2:

Consider the following keyValueStore object :

var keyValueStore = (function() {
    var count = 0;
    var kvs = function() {
        count++;
        this.data = {};
        this.get = function(key) { return this.data[key]; };
        this.set = function(key, value) { this.data[key] = value; };
        this.delete = function(key) { delete this.data[key]; };
        this.getLength = function() {
            var l = 0;
            for (p in this.data) l++;
            return l;
        }
    };

    return  { // Singleton public properties
        'create' : function() { return new kvs(); },
        'count' : function() { return count; }
    };
})();
click below button to copy the code. By JavaScript tutorial team

We can create a new instance of this object by doing this :

kvs = keyValueStore.create();
click below button to copy the code. By JavaScript tutorial team

Each instance of this object would have the following public properties :

  • data
  • get
  • set
  • delete
  • getLength

Now, suppose we create 100 instances of this keyValueStore object. Even though get, set, delete, getLength will do the exact same thing for each of these 100 instances, every instance has its own copy of this function. Now, imagine if we could have just a single get, set, delete and getLength copy, and each instance would reference that same function. This would be better for performance and require less memory. That's where prototypes come in. A prototype is a "blueprint" of properties that is inherited but not copied by instances. So this means that it exists only once in memory for all instances of an object and is shared by all of those instances. Now, consider the keyValueStore object again. We could rewrite it like this :

var keyValueStore = (function() {
    var count = 0;
    var kvs = function() {
        count++;
        this.data = {};
    };

    kvs.prototype = {
        'get' : function(key) { return this.data[key]; },
        'set' : function(key, value) { this.data[key] = value; },
        'delete' : function(key) { delete this.data[key]; },
        'getLength' : function() {
            var l = 0;
            for (p in this.data) l++;
            return l;
        }
    };

    return  {
        'create' : function() { return new kvs(); },
        'count' : function() { return count; }
    };
})();
click below button to copy the code. By JavaScript tutorial team

This does EXACTLY the same as the previous version of the keyValueStore object, except that all of its methods are now put in a prototype. What this means, is that all of the 100 instances now share these four methods instead of each having their own copy.

Solution 3:

When a constructor creates an object, that object implicitly references the constructor’s “prototype” property for the purpose of resolving property references. The constructor’s “prototype” property can be referenced by the program expression constructor.prototype, and properties added to an object’s prototype are shared, through inheritance, by all objects sharing the prototype.

Solution 4:

The interface to standard classes become extensible. For example, we are using the Array class and we also need to add a custom serializer for all our array objects. Would we spend time coding up a subclass, or use composition or ... The prototype property solves this by letting the users control the exact set of members/methods available to a class. Think of prototypes as an extra vtable-pointer. When some members are missing from the original class, the prototype is looked up at runtime.

Solution 5:

Every object has an internal property, [[Prototype]], linking it to another object:

object [[Prototype]] -> anotherObject Some environments expose that property as __proto__: anObject.__proto__ === anotherObject We create the [[Prototype]] link when creating an object:

var object = Object.create(anotherObject)
// imagine:
// object.__proto__ = anotherObject

// or (ES6 only):
var object = { __proto__: anotherObject };
click below button to copy the code. By JavaScript tutorial team

In traditional javascript, the linked object is the prototype property of a function:

object [[Prototype]] -> aFunction.prototype
click below button to copy the code. By JavaScript tutorial team

and we create the [[Prototype]] link with new:

var object = new aFunction;
// imagine:
// object.__proto__ = aFunction.prototype;
click below button to copy the code. By JavaScript tutorial team

So these statements are equivalent:

var object = Object.create(Object.prototype);
var object = new Object;
// object.__proto__ === Object.prototype
click below button to copy the code. By JavaScript tutorial team

Related Searches to javascript tutorial - prototype