原型链继承
最简单的类声明
估计所有学过js的人都会这个吧 :p
原型链继承的标准代码
现在用一个Author类继承Person类。
做一个实际的使用:
那么问题来了。为什么类继承要这么写?这里面发生了什么?
首先看prototype属性的定义:
- js中任意对象都有prototype属性,记为__proto__.
- 原型链相当于一个链表,链表中的一个位置相当于指针,指向下一个结构体;
- 当定义一个prototype的时候,相当于把该实例的__proto__指向一个结构体,这个被指向结构体即为该实例的原型。
- 默认指向: Object.prototype
- Object.prototype.__proto__ === null 此为顶端。
如下图的foo对象:
原型链如何产生?
看一段代码。
如上代码所示,以b为例,当b有明确的__proto__属性时,执行b.add(30)的时候,先在自己的属性里面找,没找到,就到上级的__proto__属性中找,如果还没找到就继续往上找……这样就构成了一条原型链。
回到原来的问题: 为什么要使用Author.prototype = new Person()?
实际做的事情:
所以,执行这Author.prototype = new Person()后,相当于形成了一条原型链。
为什么要使用Author.prototype.constructor = Author?
因为定一个函数的prototype时,默认情况下prototype属性会默认获得一个constructor属性,是一个指向prototype构造函数的指针。
所以,执行完Author.prototype = new Person()后,隐式声明了
而在实际的开发过程中,经常要修改子类的prototype, 比如我们又定义了一个Author的子类FictionAuthor:
所以,在子类继承中我们在执行完Author.prototype = new Person()后,需要对构造函数constructor做一个修正,即:
这样就达到了我们想要的结果。
综上,可以总结一个extend函数: