原型

最近一周都没什么事干,就认真的看了一下js的原型,感觉自己终于有点理解了。

原型

对于原型,有两个概念要知道:__proto__prototype

__proto__

实例对象有__proto__属性

prototype

函数对象有prototype属性。哪些是函数对象呢?

1
2
3
function A(){}
var a = function(){}
new Function(){}

这些便是了。

constructor

原型对象上有一个constructor属性,用来指向它的函数对象。

例子

在javascript中,一切接对象!所以函数也是对象。当我们定义了一个对象时,该对象会自带一些属性。如果你只是一个普通对象,那你就会有__proto__属性,而如果你是一个函数的话,那你不只有__proto__,还有prototype。
举个栗子

1
2
3
4
5
6
let Person = function(){};
let boy = new Person();
console.log('instance __proto__', boy.__proto__);
console.log('instance prototype', boy.prototype);
console.log('function __proto__', Person.__proto__);
console.log('function prototype', Person.prototype);

得到的结果如下:

1
2
Person.prototype.constructor === Person
//true

其实就是一种循环引用,Person通过prototyop属性指向Person.prototypo这个原型对象,而这个原型对象又通过constructor这个属性指向回Person。

当js在创建对象时,它就会不知通过什么方式自动为这个对象创建__proto__这个属性,它相当于一个指针,指向该对象的构造函数的prototype属性,用上个例子来说就是

1
boy.__proto__ == Person.prototype

是时候献上神图了

原型链

一个实例的__proto__指向它的构造函数的原型对象,而它的构造函数的原型对象也有__proto__,继续指向它自己的原型对象,如此重复下去,知道最后一个Object.prototype,可以说它是一切对象的始祖,一切对象都是继承它来的,Object.prototype.__proto__为null,不在指向其它对象。这样便构成了一条原型链。