• 一起手写吧!ES5和ES6的继承机制!


    原型

    执行代码var o = new Object();

    此时o对象内部会存储一个指针,这个指针指向了Object.prototype,当执行o.toString()等方法(或访问其他属性)时,o会首先查看自身有没有该方法或属性,如果没有的话就沿着内部存储的指针找到Object.prototype对象,然后查看Object.prototype对象是否有对应名称的方法或属性,如果有就调用Object.prototype的方法或属性。

    我们把这个指针叫做o对象的原型。

    ES3规范中定义了Object.prototype.isPrototypeOf()方法,该方法可以判断某个对象是不是另一个对象的原型。Object.prototype.isPrototypeOf(o)返回true值可以确定Object.prototype就是o对象的原型。

    在ES3规范中,不能直接读取o对象的原型,也就是o对象的原型看不见摸不着的。ES5.1规范定义了Object.getPrototypeOf()方法,通过该方法可以获取对象的原型。我们可以通过Object.getPrototypeOf(o) === Object.prototype再次验证Object.prototype就是o对象的原型。

    ES6规范更加直接,为对象添加了一个__proto__属性,通过这个属性就可以获得对象的原型,所以在支持__proto__的浏览器中,o.__proto__ === Object.prototype也会返回true。

    当我们执行var x = new X();时,浏览器会执行x.__proto__ = X.prototype,会将实例化对象的原型设置为对应的类的prototype对象,这一点很重要。

    原型链 

    我们执行如下代码:

    function Person(){};
    var p = new Person();

    p.__proto__指向了Person.prototype,Person.prototype的原型是Person.prototype.__proto__,其指向了Object.prototype,Object.prototype.__proto__为null。

    通过__proto__向上追踪形成了如下的链式结构:

    p -> Person.prototype -> Object.prototype -> null

    这一原型的链式结构就叫做原型链。Object.prototype的原型是null,也就是说Object.prototype没有原型。

    JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依此层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。

    JavaScript中的继承是通过原型实现的,虽然在ES6中引入了class关键字,但是它只是原型的语法糖,JavaScript继承仍然是基于原型实现的。 

    ES5寄生组合继承 (业内比较提倡的方法)

    即通过借助构造函数来继承属性,通过原型链的混成形式来继承方法。
    其背后的基本思路是:不必为了指定子类型的原型而调用超类型的构造函数,我们所需要的无非就是超类型原型的一个副本而已。本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。
    function inserit(son, father) {
        var obj = Object.create(father.prototype);
        son.prototype = obj;
        obj.constructor = son
    }
    
    function SuperType(name, colors) {
        this.name = name;
        this.colors = colors;
    }
    SuperType.prototype.sayName = function () {
        return this.name;
    }
    
    function SubType(job, name, color) {
        SuperType.call(this, name, color);
        this.job = job;
    }
    //核心方法
    inserit(SubType, SuperType);
    SubType.prototype.sayjob = function () {
        return this.job;
    }
    var instance = new SubType("doctor", "John", ["red", "green"]);
    console.log(instance.sayjob(), instance.sayName()) //doctor,John

    ES6继承

    ES6支持通过类来实现继承,方法比较简单,代码如下

    class Point {
        constructor(x, y) {
            this.x = x
            this.y = y
        }
        
        toString() {
            return this.x + '' + this.y
        }
    }
    
    class ColorPoint extends Point {
        constructor(x, y, color) {
            super(x, y) //调用父类的constructor(x, y)
            this.color = color
        }
        
        toString() {
            return this.color + ' ' + super.toString() // 调用父类的toString()
        }
    }
    
    var colorPoint = new ColorPoint('1', '2', 'red')
    
    console.log(colorPoint.toString())  // red 12
  • 相关阅读:
    Redis(二)
    Redis(一)
    MyBatis--一级二级缓存
    MySQL优化
    HashMap
    ArrayList
    常用框架注解说明
    Linux常用基础命令
    SpringCloud--gateway路由配置
    JetBrains系列软件的插件安装
  • 原文地址:https://www.cnblogs.com/magicg/p/12735202.html
Copyright © 2020-2023  润新知