原型链的个人摘抄 from 高程(三)

本文深入探讨JavaScript中的多种继承方式,包括原型链继承、借用构造函数、组合继承等,并重点介绍了组合式继承和寄生组合式继承的特点及其实现方法。

继承的要点

  1. proptotyp和[[prototype]]。这两个分别为显式原型和隐式原型。
    • 显示是用来实现基于原型链的继承和属性共享 (implement prototype-based inheritance and shared properties),指向原型对象。隐式是也是用来构成原型链的(_proto_是不规范的浏览器实现,可直接使用),指向创建这个对象的原型对象。
    • 构造函数都有一个原型对象,原型对象存在一个constrcutor属性指向构造函数。构造函数的实例的[[prototype]]属性不可访问,可用Object.getPrototypeOf()标准方法访问该属性,返回为原型对象。
  2. 原型链实现的本质是重写子类的原型对象。原型对象的赋值一旦采用了字面量形式,那么原型就被重写,constrcutor属性指向Object,原型的[[prototype]]指向超类原型。实例与原型对象的[[proptotype]]就完成了链的连接。

继承方法的个人记忆

  • 着重记忆组合式继承+寄生组合式继承,这两种都是由另外两种继承组合而成,要组合当然是因为它们各自有各自的缺陷。而两者相似的地方都是用子类构造函数来继承属性(此处是调用超类构造(call/apply),得到一个副本),用子类原型来继承方法。(前者new,后者create)
  • 记住Object.create(),它是原型式继承的规范化。是寄生组合式继承的重要部分。

共用超类代码

function Super() {
    this.value = ['a', 'b', 'c']
}
Super.prototype.getValue = function () {
    return this.value.
}
复制代码

一: 原型链继承

//代码实现
function Sub() {}
Sub.prototype = new Super()
var instance = new Sub() //使用
复制代码

缺点:

  1. 原型中有引用类型,实例可以修改,不安全.
    instance.value[3] = 'd'
    var instance2 = new Sub()
    instance2.value //['a','b','c','d'] 共享的本质
复制代码
  1. 不能给超类的构造函数传递参数

二:借用构造函数

    function Sub() {
        //继承属性
        Super.call(this,arguments) //将Super当作普通函数调用
    }
复制代码

缺点:

  • 虽然解决了向超类传参的问题,但是由于没有new,使得超类原型里的方法对子类来说不可见

三:组合继承式 = 一 + 二

    function Sub(){
        Super.call(this,arguments)
    }
    Sub.prototype = new Super()
    Sub.prototype.constructor = Sub //原型被重写,保持指向
    Sub.prototype.fun = () => ()
复制代码

解析:

  1. 该方法解决了一二的缺陷,使用instanceof和**isPrototype()**能识别基于三创建的对象。是最常用的方法。
  2. 唯一不足是调用了两次Super()

四:原型式继承

    var Person = {}
    function object(o) {
        function F() {}
        F.prototype = o
        return new F()
    }
复制代码

解析:

  1. 该方法一样存在共享引用类型值的问题
  2. 应用场景为只想让一个对象与另一个对象保持类似的情况。为此ES5有Object.create()规范了原型式继承:接受两个参数,第一个为作为新对象原型的对象,第二个为新修对象的额外属性

五:寄生式继承(不重要)

    function obj(o) {
        let clone = Object.create(o)
            clone.fun = () => ()
        return clone
    }
复制代码

解析: 无法函数复用。

六:寄生组合式继承

    function inheritPrototype (Sub, Super) {
        let obj = Object.create(Super.prototype)
            obj.constructor = Sub
            Sub.prototype = obj
    }
    function Sub() {
        Super.call(this,arguments) //属性继承
    }
    inheritPrototype(Sub,Super)
    Sub.prototype.fun = () => () //添加自己的原型方法
复制代码

解析: 解决了组合式继承的使用了两次构造函数的问题。很理想的方法。

    todo : 配图
    写的难看勿喷,这算是个人的读书笔记吧。
    如有错误请指正,谢谢。
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值