经过几天研究查找资料,对原型终于有点理解了,今天就做下总结,不对之处,希望各位能够提出。
1、每一个Javascript对象(null除外)都和另一个对象相关联,“另一个”对象就是我们今天所要总结的原型,每一个对象都从原型继承属性。
2、所有通过对象直接量创建的对象都具有同一个原型对象,并可以通过Javascript代码Object.prototype获取对原型对象的引用。
3、通过关键字new和构造函数调用创建的对象的原型就是构造函数的prototype属性的值。
看下图
这幅图是从一个外国网站(mollypages.org)上看到的,具体地址已经忘记了。
可以使用一下代码作为解释:
1 function Foo(){}; 2 var f1=new Foo(); 3 var o1=new Object();
按照上图可得出一下等式:
f1._proto_ === Foo.prototype
f1._proto_.constructor === Foo
Foo._proto_ === Function.prototype
Foo.prototype.__proto === Object.prototype
f1.__proto__.__proto__ === Object.prototype
o1._proto_ === Object.prototype
Object._proto === Function.prototype // Object instanceof function ==>true(可以解释为Object是Function的实例)
Function._proto_ === Object.prototype // Function instanceof Object ==>true(Function是Object的实例)
在Object中__proto__是Function,prototype是Object。
在Function中__proto__是Function,prototype也是Function。
所以,我们可以有如下结论:
1、Function的__proto__和prototype就是一个,扩展任何一个都是相同的效果。
2、Object的__proto__就是Function.prototype。当我们扩展Object.__proto__时,就相当于扩展了Function.prototype和__proto__,反之亦然。
从实际效果上来说,可以认为__proto__是用来扩展Function的,可以直接调用,不需要new出对象才能用,同时对象是不会通过扩展__proto__的方法或属性的。
Foo.__proto__.test="__proto__ test "; //通过__proto__扩展 alert("Foo:"+Foo.test); //可以访问
Foo.prototype.test="prototype test"; alert("Foo instance:"+f1.test); //可以执行