ziwei3749 / blog

已停止更新..转移至 https://segmentfault.com/u/ziwei3749
9 stars 1 forks source link

继承 #9

Open ziwei3749 opened 6 years ago

ziwei3749 commented 6 years ago

继承

继承1: 利用父构造函数继承

function Animal(){
    this.type = 'animal'
}

function Human(){
    Animal.call(this)
    this.color = 'yellow'
}

这种继承和原型链无关,也没有什么副作用,就是调用了Animal,而且是把它当普通函数调用了一下。

缺点是无法继承原型链上的属性

继承2: 利用原型链继承

function Animal(){
    this.type = 'animal'
}

function Human(){
    Animal.call(this)
    this.color = 'yellow'
}

Human.prototype = Animal.prototype
Human.prototype.eat = function(){console.log('eat')}

var h1 = new Human()

缺点 : 这种继承可以得到Animal原型链上的属性,但是导致我们无法判断h1是直接继承自Animal还是Human

因为通过 h1 instanceof Human && h1 instanceof Animal 都是对的 而通过constructor判断的话,他们都是指向的Animal 就算你修改指向 Human.prototype.constructor = Human 也没有意义。因为2个对象是不同的引用指向同一个内存空间。

完善继承2

function Animal(){
    this.type = 'animal'
}

function Human(){
    Animal.call(this)
    this.color = 'yellow'
}

Human.prototype = Object.create(Animal.prototype)
Human.prototype.constructor = Human
Human.prototype.eat = function(){console.log('eat')}

var h1 = new Human()

Object.create()作用就是接受对象,返回一个空对象。

但是这个空对象的原型链上挂着参数对象的属性。

实现Object.create

function Fn(){}
Fn.prototype = Animal.prototype
Human.prototype = new Fn()

这个就是没有Object.create时,ES3的写法

ES6的继承

        class Animal {
                    constructor() {
                        this.type = 'animal'
                    }
                    eat() {
                        console.log( 'eat' )
                    }
                }

        class Human extends Animal {
            constructor() {
                super()
            }

            useTools() {
                console.log( 'useTools' )
            }
        }

        var h1 = new Human()

实现new语法糖

    function newFn( fn, ...params ) {
            const obj = {}
            const Constructor = [].shift.call( arguments )
            obj.__proto__ = Constructor.prototype
            var result = Constructor.apply( obj, arguments )
            return typeof result == 'object' ? result : obj
        }