An example of possibilities - JS Inheritance

A series: a look at Liezi knowledge to make a point

1. First, we come to a simple, ES6 write an inheritance

It is not very happy, this is written in C # it? JS also inherited Oh so simple, it is also looking to make Shane

class father {
}
class child extends father {
}

2. But this is ES6 it in the code of babel turn into ES5 it follows, we take a look at it

"use strict";

// 获取对象上面的属性
var _get = function get(_x, _x2, _x3) {
    var _again = true;
    // 循环往上查找属性
    _function: while (_again) {
        var object = _x, property = _x2, receiver = _x3;
        _again = false;
        if (object === null) // 为空就变回原来的亲生父母Function调用
            object = Function.prototype;
        var desc = Object.getOwnPropertyDescriptor(object, property); // 获取属性的描述,比如constructor的描述
        if (desc === undefined) { // 没有属性描述,则往原型上找,就是小蝌蚪找妈妈
            var parent = Object.getPrototypeOf(object);
            if (parent === null) {
                return undefined;
            } else {
                _x = parent;
                _x2 = property;
                _x3 = receiver;
                _again = true;
                desc = parent = undefined;
                continue _function;
            }
        } else if ("value" in desc) { // 属性描述里面的value就是这个属性的指向,返回
            return desc.value;
        } else {
            var getter = desc.get;
            if (getter === undefined) {
                return undefined;
            }
            return getter.call(receiver);
        }
    }
};

// 类的继承
function _inherits(subClass, superClass) {
    // 判断了一下类型检查,否则抛错
    if (typeof superClass !== "function" && superClass !== null) {
        throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
    }

    // 作为一个函数的原型属性继承!!!
    // 以父类原型属性为模板,创建对象给子类的原型属性,同时把函数的constructor指向了自己
    // 这样子类通过这种方式继承了父类的原型属性,有上面的东西啦
    // Object.create标明这里子类和父类的原型属性不是同一个,新创建了一个
    subClass.prototype = Object.create(superClass && superClass.prototype, {
        constructor: { // 更改原有函数的constructor的指向,以后我生出的孩儿,都要知道我才是他们妈妈
            value: subClass, // 你看,指向了自己了吧
            enumerable: false, // 不可枚举
            writable: true, // 可写
            configurable: true // 可配置
        }
    });

    // 作为一个对象的原型指向继承!!!
    // 彻底改变子类原型,指向父类,标明我是父类创建哒, Object.setPrototypeOf这个是ES6的语法,等同于subClass.__proto__ 
    // 那么如果这里不设置的话,我们可以看到subClass.__proto__ === Function.prototype, 还是由原生Function创建的
    // 所以这里的作用就是彻底撇清和亲生父母Function的关系,彻底投靠给了养父母SuperClass, 你通过__proto__查户口本我也是superClass的儿子
    // 当然subClass.__proto__.__proto__ === superClass.__proto__ === Function.prototype 这下你爷爷变成Function了
    if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}

// 判断是否是继承此类的实例
function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
        throw new TypeError("Cannot call a class as a function");
    }
}

// 1. 父类的函数声明
var father = function father() {
    _classCallCheck(this, father);
};

// 2. 子类的函数声明
var child = (function (_father) {
    // 3. 继承
    _inherits(child, _father);

    // 4. 返回真实函数声明
    function child() {
        // 5. 判断调用者是否是当前实例
        _classCallCheck(this, child);

        // 6. 调用父类上的constructor构造函数来创建实例,就是调用父类函数创建对象
        //    Object.getPrototypeOf(child.prototype) === child.prototype.__proto__ :这里是找原型属性的原型,找到father啦
        //    为什么能找到呢, Object.setPrototypeOf(subClass, superClass) , 就是这句话的效果撒
        //    一开始以为是自己的原型,都快被绕晕了
        _get(Object.getPrototypeOf(child.prototype), "constructor", this).apply(this, arguments);
    }
    return child;
})(father);

  • Wow, good length, this code still have the last looks, attention probably steps are divided into six steps, a close look at the source code comments Oh!
  1. Function declaration parent class, here is very simple, the original class is a function ah, although I already know, there is only one father used to verify the time to create the object, this is not the father of examples
var father = function father() {
    _classCallCheck(this, father);
};
  1. Subclass function declaration, we look at the outermost, into a closure of yo, incoming parameter is father, because we specify are inherited father Well, it is necessary to father in the new Child (), when he father here to save up
var child = (function (_father) {
    _inherits(child, _father);
    function child() {
        _classCallCheck(this, child);
        _get(Object.getPrototypeOf(child.prototype), "constructor", this).apply(this, arguments);
    }
    return child;
})(father);
  1. Inheritance: It says the only thing saved from the father, save it is to inherit yo, is the phrase _inherits(child, _father);a little sentence is how to achieve it, look at this function is as follows
function _inherits(subClass, superClass) {
    if (typeof superClass !== "function" && superClass !== null) {
        throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
    }
    subClass.prototype = Object.create(superClass && superClass.prototype, {
        constructor: { // 更改原有函数的constructor的指向,以后我生出的孩儿,都要知道我才是他们妈妈
            value: subClass, // 你看,指向了自己了吧
            enumerable: false, // 不可枚举
            writable: true, // 可写
            configurable: true // 可配置
        }
    });
    if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}

Here the most important steps,

  • Inherit property as a prototype of a function! ! !
    subClass.prototype = Object.create(superClass && superClass.prototype, {
        constructor: { // 更改原有函数的constructor的指向,以后我生出的孩儿,都要知道我才是他们妈妈
            value: subClass, // 你看,指向了自己了吧
            enumerable: false, // 不可枚举
            writable: true, // 可写
            configurable: true // 可配置
        }
    });

To the parent class prototype property as a template to create the prototype property of the object subclass, while pointing to the constructor function of its own, like this class inherits the parent class prototype property in this way, there is something above it, Object.create indicate here the prototype property of the child class and parent class is not the same, creating a new

  • As a prototype of an object pointing to inherit! ! !
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;

Completely changed the subclass prototype, pointing to the parent class, I indicated is the parent class to create a clatter, Object.setPrototypeOf this is ES6 grammar, equivalent to subClass. Proto , so if this is not set, we can see subClass. Proto === Function.prototype, or protozoan Function created, so the role here is to completely disassociate themselves and Function of birth parents, adoptive parents gave refuge completely SuperClass, you pass proto Cha Hukou this is my son superClass course subClass. proto . proto === superClass. proto === Function.prototype it under your grandfather became a Function

  1. Return true function declaration, simple sentence, the function returns the child, like father, or a function that way

  2. Determine whether the caller is the current instance, the same as with the parent class

  3. The constructor calls the constructor of the parent class to create an instance, is called the father function to create objects

_get(Object.getPrototypeOf(child.prototype), "constructor", this).apply(this, arguments);

Note that this is Object.getPrototypeOf(child.prototype)equivalent to child.prototype.__proto__equivalent to father.prototype, we go to understand it to understand this sentence, I would like to call on the parent class constructor to create with this elephant, so the inheritance you create an object, layer by layer is really up call constructor to create the object you drop, specifically _getin how to get the constructor to see the source code it,

3. Finally, attach the inheritance graph bloggers fortunate fortunate it hard to draw, is not very clear of it, yes, there js deep inheritance to do with it, the so-called one two, two three here, three things , where a is the nullah, like give praise yo! ! !

4621290-662b434bb0e8b134.jpg
Javascript inheritance Detailed .jpg

Reproduced in: https: //www.jianshu.com/p/0ff7b7d73758

Guess you like

Origin blog.csdn.net/weixin_33757911/article/details/91233377