javascript object model

the difference between prototype property and [[prototype]] which constructs the chain of prorotype

  1. 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)
  2. each Function object has a explicit property called 'prototype '
  3. 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
  4. 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 is
    var str = new Object('str');
     then the value is the built-in String constructor ; if the expression is
    var 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)

  1. create an object obj of built-in Object constructor and initialize it.
  2. 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 .
  3. regard obj as this, and call the inner [[call]] method of func with the arguments.
    1. the [[call]] method creates the execution context.
    2. invoke the body of func.
    3. destroy the execution context.
    4. return the value of func if exists, otherwise return undefined.
  4. 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)

  1. create an object fn of the built-in Object constructor.
  2. assign the value of [[prototype]] property of fn to Function.prototype .
  3. set the inner [[call]] property, which is an inner implemented method.
  4. set the inner [[construct]] property, which is also an inner impelmented method.
  5. set fn.length to args.length, or set to 0 if doesnt specify arguments
  6. create an object fnProto using the same logic as new Object();
  7. set fnProto.constructor to fn .
  8. set fn.prototype to fnproto .
  9. 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 )

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 .