ES5继承模式

  果真,感受有些东西不整理一下仍是很容易忘记的,不少时候有须要不断地去复习,感受JavaScript这门语言整体上不能算是特别难,可是知识点特别杂(坑也特别多...),感受最好仍是可以梳理出一个总体架构出来javascript

  好了,废话很少说,今天大体上总结一下ES5中的继承模式,大体上仍是参照《JavaScript高级程序设计》上来的。java

  1. 原型模式架构

     function Person (name, age) {
         this.name = name;
         this.age = age;
     }
     ​
     Person.prototype.sayName = function () {
            return this.name;
     }
        Person.prototype.sayAge = function () {
            return this.age;
        }
     ​
        function Student (name, age, school) {
            this.name = name;
            this.age = age;
            this.school = school;
        }
     ​
        Student.prototype = new Person();
        Student.prototype.saySchool = function () {
            return this.school;
        }
     ​
        let stu = new Student('zhang', 18, 'zust');
        console.log(stu.getName()); // 'zhang'
     ​

   以上的继承方式是比较好理解的,当访问Student实例的sayName()方法时,先遍历实例方法(无匹配),再搜索函数

   原型对象Person实例(无匹配), 最后搜索Person.prototype对象上,获得sayName()方法。优化

  1. 借用构造函数this

     function Person(name, age){
         this.name = name;
         this.age = age;
     }
     ​
     Person.prototype.sayName = function () {
         return this.name;
     }
     ​
     Person.prototype.sayAge = function () {
         return this.age;
     }
     ​
     function Student(name, age, school){
         Person.call(this, name, age);
         this.school = school;
     }
     ​

    所谓的借用构造函数是借用父类的构造函数来设置本身的属性,进一步避免了代码的重复。spa

    以上是单纯使用了借用构造函数实现的继承,能够看到在子类中经过重用父类的构造方法为子类设置属性,可是仅仅使用借用构造函数,子类将没法继承父类构造函数原型中的方法。prototype

  2. 组合式继承(原型模式与借用构造函数的组合)设计

     function Person(name, age){
         this.name = name;
         this.age = age;
     }
     Person.prototype.sayName = function () {
         return this.name;
     }
     Person.prototype.sayAge = function () {
         return this.age;
     }
     ​
     function Student(name, age, school) {
         Person.call(this, name, age);
         this.school = school;
     }
     ​
     Student.prototype = new Person();
     ​

    以上的继承方式是原型模式和借用构造函数模式的组合方式,经过原型链的方式继承父类构造函数原型对象上的方法,使用借用构造函数重用父类构造函数中的代码。至关因而对于原型链继承模式的优化,将父类构造函数中的代码加以重用。对象

  3. 原型式继承

     let sup = {name: 'zhang', age: 18};
     let extend = function (obj) {
         function F () {};
         F.prototype = obj;
         return new F();
     }
     ​
     let sub = extend(sup);
     console.log(sub.name);

    就以上的继承方式而言,我的感受与如下实现方式并无太大区别

     let sup = {name: 'zhang', age: 18};
     let sub = {};
     Object.setPrototypeOf(sub, sup);
     console.log(sub.name);

    在子类对象建立的过程当中,全部的父类变量将会被子类共享,尤为是引用类型的变量

     const sup = {name: 'zhang', age: 18, arr: ['a', 'b', 'c']}
     ​
     const extend = function (obj) {
         function F(){};
         F.prototype = obj;
         return new F();
     }
     const a = extend(sup);
     const b = extend(sup);
     console.log(a.arr); // ['a', 'b', 'c']
     b.arr.push('d');
     console.log(a.arr); // ['a', 'b', 'c', 'd']

    在原型上定义了一个引用类型的属性arr,而后经过继承建立两个对象,经过对象b访问arr属性时,因为对象b上并无arr属性,所以,会访问b的原型对象,也就是sup对象中的arr属性,这是全部子类对象共享父类对象中的属性的实质。

    ES5中经过Object.create()方法实现原型式继承的标准API

  4. 寄生式继承

     function createPerson (obj) {
         var clone = Object.create(obj);
         clone.getName = function () {
             return this.name;
         }
         return clone;
     }
     ​
     var person = {name: 'zhang', age: 18};
     var p = createPerson(person);
     console.log(person.name); // 'zhang'

    寄生式继承是将原型式继承以及增长实例方法这两个步骤封装成一个工厂函数,而后将生成的对象返回

    代码仍是比较简单的,可是具体是干吗用的,emmmmmm...因此,再也不赘述

  5. 寄生组合式继承

     function Person (name, age) {
         this.name = name;
         this.age = age;
     }
     ​
     Person.prototype.getName = function () {
         return this.name;
     }
     ​
     Person.prototype.getAge = function () {
         return this.age;
     }
     ​
     function Student (name, age, school) {
         Person.call(name, age);
         this.school = school;
     }
     ​
     Student.prototype = Object.create(Person.prototype);
     Student.prototype.getSchool = function () {
         return this.school;
     }

    这种继承方式能够看作是组合式继承的优化,咱们能够看到,其实这种方式与组合式继承其实并无太大区别,区别仅仅在于设置Student.prototype的方式不一样。组合式继承是经过new Person()的方式产生一个原型对象,而寄生组合式继承是经过Object.create()方法产生一个通过浅复制获得原型对象的一个副本。

相关文章
相关标签/搜索