美文网首页
06-2 | 读JavaScript 高程

06-2 | 读JavaScript 高程

作者: cemcoe | 来源:发表于2020-05-27 20:45 被阅读0次

    接上篇

    经过一番的折腾,我们已经能够像女娲一样造人了,现在要做的就是如何让我们造出来的人能够进化,站在巨人的肩膀上不断地发展,术语叫做继承。

    知识点:
    1.什么是原型链?如何使用原型链实现继承?
    2.如何确定实例和原型的关系?
    3.使用原型链实现继承有什么缺点?
    4.实现继承的可选方案有哪些?
    5.ES6如何实现继承?

    继承的思路是使用原型让一个引用类型继承另一个引用类型的属性和方法。

    1.什么是原型链?如何使用原型链实现继承?

    前面提到过构造函数,原型和实例三者之间的关系。

    现在假设原型等于另一个类型的实例,那么此时原型和实例的结合体会指向另一个原型,如果再假设此原型是另一组原型和实例的结合,那么该原型会指向另一个原型,这就是原型链。文字有点绕,画个图。

    站在 A 实例的角度来看,有这么一个指向关系,A实例->A原型=B实例->B原型=C实例->C原型,这就是原型链的名字的意义。

    原型链形成的关键是一个原型和另一个实例的链接,正是这种链接将两种原型连到了一块。下面用代码来看一下原型链。

    // 先搞定A相关代码
    // A Function
    function A() {
      this.name = name
    }
    // A prototype
    A.prototype.getName = () => console.log(this.name)
    
    // B Function
    function B() {
      this.age = 18
    }
    // B prototype
    B.prototype.getAge = () => console.log(this.age)
    
    // 继承的关键代码 A 继承 B  A 的原型指向了 B 实例,
    A.prototype = new B()
    
    // 现在 A 原型拥有了 B 实例中的属性和方法
    

    2.如何确定实例和原型的关系?

    本来呢,确定实例和原型的关系很简单,但现在有了原型链,作为一个链条结构,确定实例与原型的关系就需要一些方法了。

    有两个方法,一个是 instanceof 操作符,另一个是 isPrototypeOf() 方法。

    两种方法的例子如下:

    // instanceof
    实例 instanceof 原型链中的构造函数 = true
    // instance 实例 什么是什么的实例吗?
    
    // isPrototypeOf 什么是什么的原型吗?
    原型.isPrototypeOf(实例)
    
    // 注意两种方法中实例的位置,有一种把字句和被字句的感觉。
    

    3.使用原型链实现继承有什么缺点?

    • 引用类型值的原型属性会被所有实例共享
    • 没有办法在不影响所有对象实例的情况下给超类型的构造函数传递参数。

    4.实现继承的可选方案有哪些?

    既然使用原型链进行继承有缺点,那么实现继承有哪些方案可选呢?

    书中提到了原型链,借用构造函数,组合继承,原型式继承,寄生式继承以及寄生组合式继承等方法。

    那么来看借用构造函数如何来实现继承。

    前面说到,原型链实现继承有两大缺点,对于其中的引用类型问题,借用构造函数可以解决。思路是在子类型构造函数内部调用超类型构造函数。

    这里要用到 call 和 apply,这两货到函数章节再说。但仅依靠构造函数,还是有些问题,方法在构造函数中定义,函数无法复用。

    那么我们可以将原型链和构造函数结合起来实现继承,这种方法被称为组合继承,思路是使用原型链实现对原型属性和方法的继承,通过借用构造函数实现对实例属性的继承。

    常用的实现继承的方法就是原型链和构造函数的组合了。

    5.ES6如何实现继承?

    class Person {
      // 构造函数
      constructor(name, age) {
        this.name = name
        this.age = age
      }
      // 原型
      sayName() {
        console.log(this.name)
      }
    }
    // 使用时没有变化
    // 创建实例对象
    const p1 = new Person('cemcoe', 18)
    
    // 继承 cemcoe 继承 Person
    class cemcoe extend Person {
      constructor(name, age) {
        super(name, age)
      }
    }
    

    不得不说关于面向对象的内容是真多。

    相关文章

      网友评论

          本文标题:06-2 | 读JavaScript 高程

          本文链接:https://www.haomeiwen.com/subject/eklmahtx.html