Prototype objects are just simple JavaScript objects and may have their own prototypes. If a prototype has a non-null reference to its prototype, and so on, this is called the prototype chain.
Object
ECMAScript deals with objects, which are an abstract form of object-orientated language. They are primitives but can be converted to objects when needed.
proto
Property __proto__
is the actual object that is used in the lookup chain to resolve methods, etc. prototype
is the object that is used to build __proto__
when you create an object with new
:
function Foo() {}
var foo = new Foo();
console.log(
foo.__proto__ === Foo.prototype, // true
foo.prototype === undefined // true
);
So prototype
is not available on the instances themselves (or other objects), but only on the constructor
functions.
prototype
is only available on functions since they are derived from Function
, and Object
but in anything else it is not. However, __proto__
is available on every object.
Also, prototype
prototype is a property of a Function
object. It is the prototype of objects constructed by that function.
getPropertyOf()
__proto__
is internal property of an object, pointing to its prototype. Current standards provide an equivalent Object.getPrototypeOf(O)
method, though de facto standard __proto__
is quicker.
You can find instanceof
relationships by comparing a function's prototype to an object's __proto__
chain, and you can break these relationships by changing prototype.
function Foo(x, y) {
this.x = x;
this.y = y;
}
var foo = new Foo();
// the following are all true
console.log(
foo.__proto__ === Foo.prototype,
foo.__proto__.__proto__ === Object.prototype,
foo instanceof Foo,
foo instanceof Object
);
Here Foo
is a constructor function. It builds an object (data structure) procedurally. foo
is an object constructed by Foo() so Foo.prototype
gets saved to foo.__proto__
at that time.
function A(){
this.x = 10;
this.calc = function(z) {
return this.x + this.y + z;
};
}
function B(){}
B.prototype = new A();
B.prototype.y = 20;
function C(){}
C.prototype = new A();
C.prototype.y = 30;
var b = new B();
var c = new C();
b.calc(30); // 60
c.calc(30); // 70
What is the difference between proto and prototype properties?
The rule is simple: if a property or a method is not found in the object itself (i.e. the object has no such an own property), then there is an attempt to find this property/method in the prototype chain.
If the property is not found in the prototype, then a prototype of the prototype is considered, and so on, i.e. the whole prototype chain (absolutely the same is made in class-based inheritance when resolving an inherited method — there we go through the class chain). The first found property/method with the same name is used. Thus, a found property is called inherited property. If the property is not found after the whole prototype chain lookup, then the undefined value is returned.
If a prototype is not specified for an object explicitly, then the default value for __proto__
is taken - Object.prototype.
getPropertyOf()
Object Object.prototype
itself also has a __proto__
, which is the final link of a chain and is set to null
.
In JavaScript, every function is actually a Function
object. And Function is one of the Fundamental objects
, along with Object.
function A() {}
A.prototype.foo = 1;
function B() {}
B.prototype = Object.create(A.prototype);
/* or, B.prototype = new A();*/
B.prototype.foo = 2;
var b = new B();
console.log(
/* b's contructor is A */
b.constructor === A, // true
b.constructor === B, // false
/* B's contructor is Function */
b.constructor === Function, // false
B.constructor === Function, // true
b instanceof B // true
);
var a = new A();
console.log(
a.__proto__ === b.__proto__.__proto__ // true
);