Prototype, proto and the new operator

  • Tutorial
In this article, I will briefly explain in examples what the __proto__, prototype properties and the operation of the new operator in JavaScript are.

__Proto__ property


Absolutely any object in JavaScript has the __proto__ property. This is a hidden system property, and not in all implementations of the language it is available to the user.
When accessing any property of an object, it is first of all searched in the object itself:
var obj = {ownProperty: 1};
console.log(obj.ownProperty);// 1
But if it is not there, the search occurs in the __proto__ property:
obj.__proto__ = {propertyOfProto: 2};
console.log(obj.propertyOfProto);// 2
If it is not there, it is searched further down the chain:
obj.__proto__.__proto__ = {propertyOfProtosProto: 3};
console.log(obj.propertyOfProtosProto);// 3
This chain is called the prototype chain.



__proto__ of any value (except null and undefined) refers to the prototype of the corresponding data type:
(0).__proto__ === Number.prototype &&
false.__proto__ === Boolean.prototype &&
"string".__proto__ === String.prototype &&
(new Date).__proto__ === Date.prototype &&
(function(){}/* new Function */).__proto__ === Function.prototype
All data types inherit from Object, which means for example:
Number.prototype.__proto__ === Object.prototype
And finally, the end of the chain:
Object.prototype.__proto__ === null

Prototype property


But then what is the prototype property? This is a common property, no different from any other property. Except for two features:

1) Functions in JavaScript have the prototype property. By default, it is an object with a single constructor property that refers to the function itself.



2) The prototype property is used when creating new objects with the new operator.

New operator


This statement does the following:

1) Creates an empty object:
var instance = {};

2) Sets __proto__ to this object by reference to the prototype of a class function:
instance.__proto__ = FnClass.prototype;

3) Applies a class function to our newly created object:
constructorReturns = FnClass.apply(instance, arguments);
(i.e., it executes the FnClass function, passing it an instance as this and arguments as an array of arguments)

4) It returns an instance of a class function, but if FnClass returned an object to us, then it:
return constructorReturns instanceof Object ? constructorReturns : instance;

I call a class function a function to which the new operator is subsequently expected to be applied. Such functions are usually capitalized.

Using __proto__ in your scripts


Because Since the __proto__ property is hidden, and is not described in the language specification, its explicit use is incorrect. So never write as I am in the examples above :) This code is for the console only.
However, two methods have finally appeared in the latest (current) ECMA Script 5 specification that allow you to manipulate the __proto__ property, Object.create and Object.getPrototypeOf.
I will explain their work in two simple examples:


//var myObj = {__proto__: {property1_OfProto: 1}}
var myObj = Object.create({property1_OfProto: 1});


//myObj.__proto__.property2_OfProto = 2
Object.getPrototypeOf(myObj).property2_OfProto = 2;

If you use an earlier version of JavaScript, you can create the Object.create method yourself:

if(!Object.create){
	Object.create = function(proto){
		var Fn = function(){};
		Fn.prototype = proto;
		return new Fn;
	}
}

With getPrototypeOf, the situation is more complicated, it can only be emulated for functions, and only if the constructor of this function has not been changed:

if(!Object.getPrototypeOf){
    if( (new Object).__proto__ !== Object.prototype ){
        // may return incorrect value if fn.prototype has been modified
        Function.getPrototypeOf = function(fn){
            if(typeof(fn)!=='function')
                throw new TypeError('Function.getPrototypeOf called on non-function');
            return fn.constructor.prototype;
        }
    }else{
        Object.getPrototypeOf = function(obj){
            return obj.__proto__;
        }
    }
}

And better, as advised in the comments, use the github.com/kriskowal/es5-shim library

Next is about classes in JavaScript ...


Also popular now: