如何在JS揭示原型模式中实现继承?

IT技术 javascript design-patterns inheritance
2021-01-27 07:22:52

如何继承/扩展使用揭示原型模式的类​​?有没有办法制作private变量和函数protected

示例基础对象:

myNameSpace.Person = function() {

    this.name= "";
    this.id = 0;

};

myNameSpace.Person.prototype = function(){
    var foo = function(){
        //sample private function
    };
    var loadFromJSON = function (p_jsonObject) {
       ...
    };
    var toJSON = function () {
       ...
    };
    var clone = function (p_other) {
       ...
    };

    return {
        loadFromJSON : loadFromJSON,
        toJSON: toJSON,
        clone: clone
    };
}();
1个回答

JavaScript 中没有受保护的变量/属性。但是,当您在同一范围内声明继承类时,您可以重用“私有”变量,当私有变量只是原型的“隐藏实用程序”时,这在您的情况下似乎是可能的。

MyNamespace.Person = function Person(params) {
    // private variables and functions, individual for each Person instance
    var anything, id;
    function execute_something() {}

    // public properties:
    this.name = "";
    this.getId = function getId(){
        // called a "privileged function", because it has access to private variables
    }
}
MyNamespace.American = function(params) {
    MyNamespace.Person.call(this, params); // inherit name and getId()
}

(function() { // new scope for
    // hidden utility functions and other private things
    function foo() { }
    function helpJSON() { }
    function fromJSON() { }
    var bar;

    (function(personProto) { // new scope for prototype module (not explicitly needed)
        // "private" /static/ variables (and functions, if you want them private)
        var personCount = 0;

        personProto.clone = function clone() {
            return this.constructor(myself); // or something
        };
        personProto.toJSON = function toJSON() {
            // use of helpJSON()
        };
        personProto.fromJSON = fromJSON; // direct use
    })(MyNamespace.Person.prototype);

    (function(amiProto) {
        // just the same as above, if needed
        amiProto.special = function() {
            // use foo() and co
        };
    })( MyNamespace.American.prototype = Object.create(MyNamespace.Person.prototype) );
})();

这是 JavaScript 的继承方式,即 American 的原型从 Person 的原型中自动继承了 clone()、toJSON() 和 fromJSON() 函数。当然可以覆盖。而且特点是

new MyNamespace.American() instanceof MyNamespace.Person; // true

当然,如果您不需要它,并且想要使用更像module的方式,您可以重用实用程序函数,即只需复制它们:

(function() {
    // hidden utility functions and other private things
    var bar;
    var personCount;
    function foo() { }
    function helpJSON() { }
    function fromJSON() { }
    function clone() {
        return this.constructor(myself); // or something
    }
    function toJSON() { }

    (function(personProto) { // new scope, not really needed
        // private variables are useless in here
        personProto.clone = clone;
        personProto.toJSON = toJSON;
        personProto.fromJSON = fromJSON;
    })(MyNamespace.Person.prototype);

    (function(amiProto) { // new scope, not really needed
        // copied from personProto
        amiProto.clone = clone;
        amiProto.toJSON = toJSON;
        amiProto.fromJSON = fromJSON;
        // and now the differences
        amiProto.special = function() {
            // use foo() and co
        };
    })(MyNamespace.American.prototype);
})();
@AndroidDev 是的,当然,你需要做new Person(params)另外,使用严格模式。
2021-03-19 07:22:52
如果你想了解更多关于继承和原型的信息,这里有一个很好的阅读:killdream.github.com/blog/2011/10/understanding-javascript-oop/...我想你可以转到继承开始的第 3 点。
2021-04-08 07:22:52
使用函数 Person(params) 会污染命名空间。
2021-04-10 07:22:52
2021-04-11 07:22:52