the difference between prototype property and [[prototype]] which constructs the chain of prorotype
- each object has a inner property called '[[prototype]] ', whose value is null or point to some object. This property is visible only for JS engine.(in firefox, this property can visited by name '__proto__ ' in js code)
- each Function object has a explicit property called 'prototype '
- the steps of finding a property property_name in an object obj :
1. return the value of obj.property_name if obj has the property.
2. return undefined if obj .__proto__ is null
3. return the value of obj .__proto__. property_name - let's take an example to view the values of the two properties in some objects with different types.
function func(){} var func_instance = new func(); var obj_instance = new Object();
we created three objects: a Function object func, an object func_instance created by func and an object obj_instace created by Object. By default, the prototype property of func is point to an object whose constructor property is point to func itself (it means func.prototype.constructor == func ), so the chain of [[prototype]] of the object created by func is point to Object.prototype ; the [[prototype]] property is assigned to Function.prototype . The proptotype property of func_instance is undefined, and the [[prototype]] property is the value of func.prototype . The obj_instance is mostly the same as func_instance, but the value of [[prototype]] is depended on the type of obj_instance. For example, if the expression isvar str = new Object('str');
then the value is the built-in String constructor ; if the expression isvar num = new Object(123);
then the value is the built-in Number constructor . if new Object() is used , then the value is the built-in Object constructor.
the process of creating an object. (var f = new func(); as example)
- create an object obj of built-in Object constructor and initialize it.
- if the type of func.prototype is Object, then set the [[prototype]] property of f to it. otherwise set the value to initialization, namely, Object.prototype .
- regard obj as this, and call the inner [[call]] method of func with the arguments.
- the [[call]] method creates the execution context.
- invoke the body of func.
- destroy the execution context.
- return the value of func if exists, otherwise return undefined.
- return the return value of [[call]] method if the type of value is Object, otherwise return obj.
from the fourth step, we kown that f maybe is not the instance of func but of Object, and the result depends on the return value of func. an example shows the two situation:
function func1(){} function func2(){return {var1:'var1'};} var instance1 = new func1(); var instance2 = new func2(); alert(instance1.constructor); // function func1(){} alert(instance2.constructor); // function Object(){...} alert(instance1 instanceof func1); // true alert(instance2 instanceof func2); // false
one point should notice here is that all objects created by the same function share the same [[prototype]] chain. So each object can only read the property in the [[prototype]] chain, the operation of write will result in the creation of a new local prototype with the same name. let's look the following example:
function func1(){} function func2(){return {var1:'var1'};} function func1(){} function func2(){this.prop = "prop in func2"} func1.prototype = new func2(); var ins1 = new func1(); var ins2 = new func2(); alert(ins1.prop); // prop in func2 alert(ins2.prop); // prop in func2 ins1.prop = "prop changed by ins1"; alert(ins1.prop); // prop changed by ins1 alert(ins2.prop); // prop in func2
the process of creating an Function object. (take var fn = funcion(args){...}; as example)
- create an object fn of the built-in Object constructor.
- assign the value of [[prototype]] property of fn to Function.prototype .
- set the inner [[call]] property, which is an inner implemented method.
- set the inner [[construct]] property, which is also an inner impelmented method.
- set fn.length to args.length, or set to 0 if doesnt specify arguments
- create an object fnProto using the same logic as new Object();
- set fnProto.constructor to fn .
- set fn.prototype to fnproto .
- return fn.
By default, from the seventh and eighth steps, the prototype of fn(any user defined function ) is set to an instance of Object, so the object created by fn has a chain of [[prototype]] which points to Object.prototype. But the behavior can be changed by explicit setting the prototype of fn. here is an example:
function func1(){} function func2(){} func2.prototype = new func1(); var ins2 = new func2(); alert(ins2.constructor); // function func1(){} alert(func2.prototype.constructor); // function func1(){}
the picture of javascript object model (quote from http://www.cnblogs.com/RicCC )
the picture tell us that :
1. Object.prototype is the end of the chain of [[prototype]] , and the [[prototype]] of Object.prototype is null .
2. the chain of [[prototype]] of all function is point to Function.prototype
3. the chain of [[prototype]] of Function point to Function.prototype .
4. the chain of [[prototype]] of Function.prototype is point to Object.prototype .