10

funny-js

原型链

js的对象类型的实现是利用原型链来实现的,所以像继承这样的东西实现起来还是蛮简单的,进入一个新的作用域然后就创建一个新的作用域哈希表用来存储本地作用域内的变量,同时将该作用域所在的作用域存为一个父引用。这样如果在本地找不到该变量,那么就去上层作用域查找。

关于原型链中的问题,我觉得__proto__prototype是最好的一个原型链问题。

var Func = function() {};
var obj = new Func(); 
obj.__proto__ === Func.prototype //true

如果细细查看,Func 和 obj 的属性中有些有意思的地方是不相同的。prototype是作为一个函数对象的属性存在,其中的值是以Func为构造函数的对象。而__proto__则是函数对象它自己本身的原型,也可以理解为父类。我自己将prototype理解为一个用于基于构造函数用来形成对象的技巧。在基于原型的基础上,想了像好像是没有什么特别好的方法用来构造对象(OOP)。

回到最初的这个问题,prototype__proto__还是有联系的,当使用new操作符来构造对象的时候,函数会调用函数中的prototype将这个属性引用给新创建的对象的__proto__。当然,所有的基于构造函数的对象,他们的构造函数的最终是基于一个function(){}。某种程度上来说,以下划线开始的函数是不适合开放的,所以prototype的出现还是有意义的,至少出现的继承就是顺着原型链来实现的。也就是说:

/*
a.property -> A.prototype -> a.__proto__.constructor.prototype......
*/

其实,这个过程还是有些饶,如果在这个对象中没有相应的属性,那么它会去调用构造函数当中的prototype,在原型中查找属性值,如果没有找到,那么会在prototype中的构造函数的prototype中继续寻找。

日常系列之系统