我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,一个对象。无论什么时候,我们只要创建一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性对象指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个 constroctor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针。例如:
function Person(){}
当我们创建这个Person函数(对象)的时候,该函数便有了一个prototype属性,它的原型对象Person.prototype会获得一个constroctor属性,那么Person.prototype.constroctor便指向了Person。更直白一点讲就是,如果我们再此基础上再加一句
var p=new Preson();
那么,p的原型就会指向构造器的prototype属性,也就是Person.prototype。
那么,原型链具体的工作机制是什么?请看下面这个例子
function foo(){} foo.prototype.z=3; var obj=new foo(); obj.y=2; obj.x=1; obj.x;//1 obj.y;//2 obj.z;//3 typeof obj.toString();//'function' 'z' in obj;//true obj.hasOwnProperty('z');//false
当输出obj.z的时候,并不会因为obj对象没有z属性而输出undefied,而是查找obj的原型也就是foo.prototype,这是js发现z的值是3,所以就会输出obj.z的值为3.
实际上,我们用对象字面量创建的函数对象,其原型obj.prototype会指向Object.prototype,而Object.prototype也是由原型的,其值是null,这是上就是一个
原型链,而这也是 typeof obj.toString(); 为function的原因,因为沿着原型链向上查找,便找到了object中的toString方法。