JavaScript继承
  # # JavaScript继承
在上篇JavaScript原型中,我们理解了原型的来源以及与其相关的constructor、new、prototype概念。下面我们来看看js是如何通过原型来实现面向对象的另外一个特征:继承。另外推荐《JavaScript高级程序设计》,js面向对象章节写的太棒了,层层递进,深入浅出。
# # 组合继承
利用 call 继承父类上的属性,用子类的原型等于父类实例去继承父类的方法。
缺点:调用两次父类Person构造函数,造成性能浪费。
    // 组合继承,也叫经典继承
    function Person(name, languages) {
        this.name = name
        this.languages = languages
    }
    Person.prototype.sleep = function() {  console.log(this.name + ' go to sleep') }
    
    function Developer(name, languages, codeLanguage) {
        // 构造函数内,使得Person实例的属性/方法,不会变成原型共享属性/方法
        Person.call(this, name, languages) // 构造函数终归也是函数
        this.codeLanguage = codeLanguage
    }
    // 继承原型
    // 原型链,使得Person实例拥有的属性/方法,都变成Developer原型的共享属性/方法
    // 单以下这一行代码会有“当属性为引用类型”的bug,所以需要配合上面Person.call
    Developer.prototype = new Person()
    Developer.prototype.constructor = Developer
    
    var jsCoder = new Developer('tom', ['Chinese', 'English'], ['js', 'css'])
    // Developer中没有定义sleep方法,但可以访问到,说明Develper继承了Person
    jsCoder.sleep() // tom go to sleep
    
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# # 寄生组合继承
用空函数的原型去等于父类原型,再用子类的原型等于干净函数的实例,从而达到消除一次执行Person函数。
    // 寄生组合继承,也是最理想的继承方式
    function Person(name, languages) {
        this.name = name
        this.languages = languages
    }
    Person.prototype.sleep = function() {  console.log(this.name + ' go to sleep') }
    
    function Developer(name, languages, codeLanguage) {
        Person.call(this, name, languages)
        this.codeLanguage = codeLanguage
    }
    
    // 利用空函数中介,实现继承
    Developer.prototype = object(Person.prototype)
    Developer.prototype.constructor = Developer
    function object(origin) { // object函数,等同于ES6中Object.create
        function F(){}
        F.prototype = origin
        return new F()
    }
    
    var jsCoder = new Developer('tom', ['Chinese', 'English'], ['js', 'css'])
    jsCoder.sleep() // tom go to sleep
    
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# # 通用继承
以上我们能得到一种通用的js继承,而这种方式也是很多js库正在使用的继承函数。
    inheritPrototype(Developer, Person)
    
    function inheritPrototype(subClass, superClass) {
        subClass.prototype = Object.create(superClass.prototype)
        subClass.prototype.constructor = subClass
        // 或者一条代码
        // subClass.prototype = Object.create(superClass && superClass.prototype, {
        //     constructor: { value: subClass, writable: true, configurable: true }
        // });
    }
    
 1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# # 参考文章
编辑  (opens new window)