【问题标题】:JS Getters/Setters on prototype inheritanceJS Getters/Setters 关于原型继承
【发布时间】:2017-12-21 09:10:05
【问题描述】:

最近我在 es6 类中编写了一个小型库。现在我决定将其重写为 es5 代码。由于库中大量使用类继承(A 类继承 B),我只好写了一小段代码来模拟 es6 类的继承:

combine.js

module.exports = function () {
    var _arguments = arguments;

    var Class = function () {
        for (var i = 0; i < _arguments.length; i++) {
            if (typeof _arguments[i] === 'function') {
                _arguments[i].call(this);
            }
        }
    }

    var prototype = { };
    for (var i = 0; i < _arguments.length; i++) {
        if (typeof _arguments[i] === 'function') {
            prototype = Object.assign(prototype, _arguments[i].prototype);
        }
    }
    Class.prototype = prototype;

    return Class
}

但据我所知,这段代码不能像这样组合在基本函数上定义的 getter/setter:

var combine = require('./combine.js');

function A() {
    this._loading = false;
}

Object.defineProperty(A.prototype, 'loading', {
    get() {
        return this._loading;
    },
    set(value) {
        this._loading = value;
    }
});

function B() { }

B.prototype.isLoading = function () {
    return this._loading;
}

B.prototype.setLoading = function (loading) {
    this._loading = loading;
}

var C = combine(A, B);
var c = new C();

console.log(c.isLoading()); // false
console.log(c.loading); // c.loading is undefined

c.setLoading(true);
console.log(c.isLoading()); // true
console.log(c.loading); // c.loading is undefined

c.loading = false;
console.log(c.isLoading()); // true
console.log(c.loading); // false

有没有办法继承函数原型上定义的getter/setter?

【问题讨论】:

  • "现在我决定将其重写为 es5 代码。" - 为什么?让转译器为您完成这项工作。
  • "B.prototype.isLoading() { return this._loading; }" 是语法错误。如果没有,请扔掉您的 Internet Explorer。
  • 是的,谢谢,只是例子中的一个错误,这段代码我实际上并没有使用
  • combine 的东西并没有真正做继承,它更像是应用 mixins。为什么不直接使用proper ES5 class inheritance
  • @Bergi 是对的。让 Babel 为您完成工作(让 IE 死于自然原因)。看npm,或者bower

标签: javascript oop inheritance javascript-inheritance


【解决方案1】:

最后,感谢@Bergi 的链接,我得到了 mixin 函数的工作原型,如下所示:

module.exports = function () {

    var _arguments = arguments;

    var Class = function () {
        for (var i = 0; i < _arguments.length; i++) {
            if (typeof _arguments[i] === 'function') {
                _arguments[i].call(this);
            }
        }
    }

    var prototype = { }
    for (var x = 0; x < _arguments.length; x++) {
        if (typeof _arguments[x] === 'function') {
            var properties = Object.getOwnPropertyNames(_arguments[x].prototype);
            for (let y in properties) {
                if (properties[y] != 'constructor') {
                    Object.defineProperty(
                        prototype,
                        properties[y],
                        Object.getOwnPropertyDescriptor(_arguments[x].prototype, properties[y])
                    );
                }
            }
        }
    }
    Class.prototype = prototype;

    return Class;

}

【讨论】:

    猜你喜欢
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    • 2015-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-06
    相关资源
    最近更新 更多