Press "Enter" to skip to content

JS原型与原型链

普通对象与函数对象

JS中,对象分为普通对象和函数对象两种,Object和Function是JS自带的函数对象。凡是通过new Function()的创建的对象都是函数对象,其他的都是普通对象。

下面这些是函数对象:

下面这些是普通对象:

原型对象

每当定义一个对象(函数)时,对象中都会包含一些预定义的属性。其中,函数对象会有一个prototype属性,其值就是我们所说的原型对象(普通对象没有prototype,但有__proto__属性;函数对象同时含有prototype和__proto__属性)。注意__proto__这里proto前后分别都是两个下划线,不是一个。

原型对象其实就是普通对象(Function.prototype除外,它是函数对象,但同时它又没有prototype属性)。

原型对象的主要作用是用于继承:

原型链

上面提到原型对象的主要作用是用于继承,其具体的实现就是通过原型链实现的。创建对象(不论是普通对象还是函数对象)时,都有一个叫做__proto__的内置属性,用于指向创建它的函数对象的原型对象(即创建它的函数对象的prototype属性)。

这个由__proto__串起来的直到Object.prototype.__proto__ ==> null对象的链称为原型链。

  • yakima的__proto__属性指向Person.prototype对象;
  • Person.prototype对象的__proto__属性指向Object.prototype对象;
  • Object.prototype对象的__proto__属性指向null对象。

下面有一些比较特别的情况,看完忘掉就可以了,如果是在准备面试,最好别看,别看混了^_^。

Object是函数对象,是通过new Function()创建的,所以Object.__proto__指向Function.prototype:

Function是函数对象,是通过new Function()创建的,所以Function.__proto__指向Function.prototype。本类创建本类。。。大概类似是这么个意思——人是人他妈生的,妖是妖他妈生的。

另外:

constructor

原型对象都有个constructor属性,用来引用它的函数对象。这是一种循环引用。

综合理解

原型和原型链是JS实现继承的一种模型。

对上例的分析:

  • Dog自身没有price属性,沿着Dog.__proto__属性往上找,因为Dog的赋值是通过var Dog = function () {}实现的,所以Dog其实是使用new Function()创建的,所以Dog.__proto__ ==> Function.prototype,Function.prototype.__proto__ ==> Object.prototype,而Object.prototype.__proto__ ==> null。很明显,整条链上都找不到price属性,只能返回undefined;
  • tidy自身没有price属性,沿着tidy.__proto__属性往上找,因为tidy对象是Dog函数对象的实例,所以tidy.__proto__ ==> Dog.prototype ==> Animal,从而tidy.price获取到了Animal.price的值。

Be First to Comment

发表评论

电子邮件地址不会被公开。 必填项已用*标注