资讯专栏INFORMATION COLUMN

JS-ES5模拟super与多级继承(二)

yearsj / 2190人阅读

摘要:参考文章官网是一个的编译器它可以将的代码转换成等价的我们看看它是怎么模拟关键字的与上面等价的语句如下貌似不支持多重继承啊覆写子类的对象设置隐式原型感觉这样很怪因为这样意为着子类将成为父类的实例对象呃类似的概念但我不觉得父子类关系与类和实

参考文章

Babel官网

babel是一个es6->es5的编译器, 它可以将es6的代码转换成等价的es5.

我们看看它是怎么模拟super关键字的.

class A{
    constructor(){
    }
    render(){
        console.log(1)
    }
}

class B extends A{
    constructor(){
        super();
    }
    render(){
        super.render();
        console.log(2);
    }
}

与上面es6等价的es5语句如下

var _get = function get(object, property, receiver) { 
    if (object === null) object = Function.prototype; 
    var desc = Object.getOwnPropertyDescriptor(object, property); 
    if (desc === undefined) { 
        var parent = Object.getPrototypeOf(object); 
        if (parent === null) { return undefined; } 
        else { return get(parent, property, receiver); } 
    } else if ("value" in desc) { 
        return desc.value; 
    } else { 
        var getter = desc.get; 
        if (getter === undefined) {
             return undefined; 
        } 
        return getter.call(receiver); 
    } 
};

var _createClass = function () { 
    function defineProperties(target, props) { 
        for (var i = 0; i < props.length; i++) { 
            var descriptor = props[i]; 
            descriptor.enumerable = descriptor.enumerable || false; 
            descriptor.configurable = true; 
            if ("value" in descriptor) 
                descriptor.writable = true; 
            Object.defineProperty(target, descriptor.key, descriptor); 
        } 
    } 
    return function (Constructor, protoProps, staticProps) { 
        if (protoProps) defineProperties(Constructor.prototype, protoProps); 
        if (staticProps) defineProperties(Constructor, staticProps); 
        return Constructor; 
    }; 
}();

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn"t been initialised - super() hasn"t been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

// 貌似不支持多重继承啊.
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); 
    } 
    // 覆写子类的prototype对象
    subClass.prototype = Object.create(superClass && superClass.prototype, { 
        constructor: { 
            value: subClass, 
            enumerable: false, 
            writable: true, 
            configurable: true 
        } 
    }); 
    // 设置隐式原型, 感觉这样很怪. 因为这样意为着子类将成为父类的实例对象...呃, 类似的概念
    // 但我不觉得父子类关系与类和实例的关系一样...
    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"); 
    } 
}

var A = function () {
    function A() {
        // 检查当前this对象是否为A的实例, 如果不是说明是当成函数直接用的...
        _classCallCheck(this, A);
    }
    // 创建类属性
    _createClass(A, [{
        key: "render",
        value: function render() {
            console.log(1);
        }
    }]);

    return A;
}();

var B = function (_A) {
    _inherits(B, _A);

    function B() {
        _classCallCheck(this, B);

        return _possibleConstructorReturn(this, (B.__proto__ || Object.getPrototypeOf(B)).call(this));
    }
    // 原型方法中取到了构造函数类本身, 感觉这样耦合性比较大
    // 这是直接到`B.prototype.__proto__`指向的原型链上寻找目标方法, 
    // 但我不想每次在写子类方法时还要显示写父类变量.
    _createClass(B, [{
        key: "render",
        value: function render() {
            _get(B.prototype.__proto__ || Object.getPrototypeOf(B.prototype), "render", this).call(this);
            console.log(2);
        }
    }]);

    return B;
}(A);

但这种转换并不是我想要的那种, 因为它的super实现实际上是在子类方法中通过显式调用父类名.父类方法的形式完成的, 作为编译结果, 它可以隐藏实际代码编写时的耦合性, 但直接写es5的语法时, 显示指定要调用的父类名称依然不能说是一种好的解决方案.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92834.html

相关文章

  • JS-ES5模拟super多级继承(一)

    摘要:参考文章多层继承方法本系列文章对实现多级继承做一个学习和探究第三篇给出最终的模拟代码及测试用例简单的父子继承父类子类原型链继承这里我用了关键字表示了继承的父类方法可以将其附加到子类实例对象上用起来会方便一点但是比较致命的一点是这种方式不适 参考文章 js多层继承 super方法 本系列文章对js es5实现多级继承做一个学习和探究, 第三篇给出最终的模拟代码及测试用例. 简单的父-子继...

    李世赞 评论0 收藏0
  • JS-ES5模拟super多级继承(三)

    摘要:参考文章多层继承方法参考文章中提供了一个思路不一定要是一个变量也可以是一个函数只要它能返回我们期望的父级对象就可以了下面是我对它给出的源码的一些修改和注释另外有个测试示例要想拥有方法必须继承类注意方法中不要再在时为子类添加指向父类本身的属 参考文章 js多层继承 super方法 参考文章1中提供了一个思路, _super不一定要是一个变量, 也可以是一个函数, 只要它能返回我们期望的父...

    VioletJack 评论0 收藏0
  • javascript之模拟继承

    摘要:欢迎关注我的博客正文让我来构造函数其实,模拟一个类的方式非常的简单构造函数。我们先来看一个例子这里通过构造函数模拟出来的类,其实和其他语言的类行为上是基本一致的,唯一的区别就是它不具备私有方法。 前言 ES6时代的来临,使得类继承变得如此的圆滑。但是,你有思考过ES6的类继承模式吗?如何去实现它呢? 类继承对于JavaScript来说,实现方式与Java等类语言大不相同。熟悉JavaS...

    Jochen 评论0 收藏0
  • ES6—class面向对象编程(8)

    摘要:接下来我们看下类的写法,这个就很接近于传统面向对象语言了。如果你想了解传统面向对象语言,这里是一个好切入点。作为对象时,指向父类的原型对象。这些就是为将来在中支持面向对象的类机制而预留的。 在ES5中,我们经常使用方法或者对象去模拟类的使用,并基于原型实现继承,虽然可以实现功能,但是代码并不优雅,很多人还是倾向于用 class 来组织代码,很多类库、框架创造了自己的 API 来实现 c...

    wangjuntytl 评论0 收藏0
  • 超级白中白的学习进程(2):继承(Extends)

    摘要:父类中的访问权限一定要小于或者等于子类访问权限的个关键字访问权限大小,其中为默认值,不用写。下面是一个典型的代码父类代码子类代码测试类代码输出结果在子类那里已经表明。 继承(Extends)1、前言还是先说一下博主本人的一些基本情况吧。本人去年刚刚毕业,专业是电气工程及其自动化,就是在大学期间完全没有接触过JAVA,也就稍稍了解了一下C语言。后来找了现在的工作也是和编程没有任何关系,是...

    pkwenda 评论0 收藏0

发表评论

0条评论

yearsj

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<