完美清晰掌握ES5构造函数实现类的继承

大城市里の小女人 提交于 2020-01-18 03:00:31

ES5中的类

  1. es5中的类

    function Person() {
        this.name = '张三';
        this.age = 12;
    }
    
    var p = new Person();
    
    console.log(p.name)
    
  2. 构造函数和原型链里面增加方法

    function Person() {
        this.name = '李四';
        this.age = 23;
        this.run = function() {
            console.log(`${this.name}运动了~`)
            // console.log(this)
        }
    }
    
    // 在原型链上扩展属性和方法(原型链上的属性会被多个实例共享,构造函数不会)
    Person.prototype.sex = '男';
    Person.prototype.work = function() {
        console.log(`性别:${this.sex}`)
    }
    
    var p = new Person();
    
    p.run();
    p.work()
    
  3. 类的静态方法

    function Person() {}
    
    Person.love = function() {
        console.log('我是类的静态方法,通过实例访问的是类的实例方法,通过类名直接访问的是类的静态方法。');
    }
    
    Person.love();
    
  4. 类的继承 原型链和对象冒充,用的最多的是两者组合继承模式

    (对象冒充) 
    function Person() {
        this.name = '李四';
        this.age = 23;
        this.run = function() {
            console.log(`${this.name}运动了~`)
        }
    }
    
    Person.prototype.sex = '男';
    Person.prototype.work = function() {
        console.log(`性别:${this.sex}`)
    }
    
    function Animal() {
        Person.call(this); // 对象冒充实现继承
    }
    
    let a = new Animal();
    
    a.run(); // 对象冒充可以继承构造函数里面的属性和方法
    a.work(); // error报错; 对象冒充可以继承构造函数里面的属性和方法,但是没法继承原型链上的属性和方法
    
  5. 类的继承(原型链)

    function Person() {
        this.name = '李四';
        this.age = 23;
        this.run = function() {
            console.log(`${this.name}运动了~`)
        }
    }
    
    Person.prototype.sex = '男';
    Person.prototype.work = function() {
        console.log(`性别:${this.sex}`)
    }
    
    function Animal() {}
    
    Animal.prototype = new Person(); // 原型链继承 可以继承构造函数里面的属性和方法,也可以继承原型链上的属性和方法
    
    let a = new Animal();
    
    a.run();
    a.work();
    
  6. 原型链继承的问题

    function Person(name, age) {
        this.name = name;
        this.age = age;
        this.run = function() {
            console.log(`${this.name}运动了~`)
        }
    }
    
    Person.prototype.sex = '男';
    Person.prototype.work = function() {
        console.log(`性别:${this.sex}`)
    }
    
    
    var p = new Person('李四', 29);
    
    p.run();
    
    function Animal(name, age) {
    
    }
    
    // 使用原型链继承
    Animal.prototype = new Person();
    
    var a = new Animal('赵武', 23); // 通过原型链继承实例化的时候没法给子类传参
    
    a.run(); // undefined运动了~
    
  7. 原型链和对象冒充组合继承

    function Person(name, age) {
        this.name = name;
        this.age = age;
        this.run = function() {
            console.log(`${this.name}运动了~`)
        }
    }
    
    Person.prototype.sex = '男';
    Person.prototype.work = function() {
        console.log(`性别:${this.sex}`)
    }
    
    
    var p = new Person('李四', 29);
    
    p.run();
    
    function Animal(name, age) {
        Person.call(this, name , age); // 对象冒充继承,实例化子类可以给父类传参
    }
    
    // 使用原型链继承
    Animal.prototype = new Person();
    
    var a = new Animal('赵武', 23); // 通过原型链继承实例化的时候没法给子类传参,但是同时也使用了对象冒充的方式就可以给父类传参
    
    a.run(); // 赵武运动了~
    a.work();
    
  8. 对象冒充+原型链组合继承的另一种写法

    function Person(name, age) {
        this.name = name;
        this.age = age;
        this.run = function() {
            console.log(`${this.name}运动了~`)
        }
    }
    
    Person.prototype.sex = '男';
    Person.prototype.work = function() {
        console.log(`性别:${this.sex}`)
    }
    
    
    var p = new Person('李四', 29);
    
    p.run();
    
    function Animal(name, age) {
        Person.call(this, name , age); // 对象冒充继承,可以继承父类构造函数中的属性和方法,且实例化子类可以给父类传参
    }
    
    // 使用原型链继承
    // Animal.prototype = new Person();
    Animal.prototype = Person.prototype; // 因为对象冒充继承了构造函数中的属性和方法且可以传参,所以通过原型链的方式继承原型上的属性和方法即可。
    
    var a = new Animal('赵武', 23); // 通过原型链继承实例化的时候没法给子类传参,但是同时也使用了对象冒充的方式就可以给父类传参
    
    a.run(); // 赵武运动了~
    a.work();
    
  9. 总结

  • function Animal(name, age) {Person.call(this, name , age);} 对象冒充的方式实现继承可以继承父类构造函数中的属性和方法,但是不能继承原型链上的属性和方法。且这种式可以给父类传参。
  • Animal.prototype = new Person();原型链的方式实现继承实例可以访问父类构造函数中的属性和方法,也可以访问原型链中的属性和方法,但是不能给父类传参。
  • 所以两者组合使用,就可以实现既能访问构造函数中的属性和方法,也能继承原型链上的属性和方法,同时也能给父类传参。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!