简体   繁体   English

扩展和覆盖JS类的私有和公共方法

[英]Extend and override JS class private and public methods

In ES5 , having the definition of a base class that provides a public API: ES5中 ,具有提供公共API的基类的定义:

var Class = function(name) {
    var self = this;
    var name = name;

    return {
        print: function() {
          printDetails();
          return this;
        },
        iAmA: function() {
            console.log('I am an instance of:', self.constructor.name);
        }
    };

    function printDetails() {
        console.log('Name', name);
    };
};

How can I: 我怎样才能:

  • extend it, without instantiate it 扩展它,而不实例化它

    Is Child.prototype = Class without new wrong? Child.prototype = Class没有new错误? I just want to define the classes and the inheritance and not instantiate any class yet. 我只想定义类和继承,而不要实例化任何类。

  • override a private method (and make it callable through public method) 重写私有方法(并使其可以通过公共方法调用)

    I want Child.print() to call Child.printDetails() , instead of Class.printDetails() . 我希望Child.print()调用Child.printDetails()而不是Class.printDetails()

  • inherit the Class public api without redeclaring it 继承Class公共api而不重新声明它

    I can return new Class(name) from Child , but I won't get my new Child methods to be called ( Class methods are called instead of the overridden ones) 我可以从Child return new Class(name) ,但不会调用新的Child方法(调用Class方法而不是重写的方法)

  • add a method to the api without redeclaring it all 在不重新声明所有内容的情况下向api添加方法

    I don't know if it is possible, but my goal is to inherit as much as possible and define just the additions/variations. 我不知道是否可能,但是我的目标是尽可能地继承并仅定义增加/变化。

The following is what I came up with, but still I don't like to instantiate a new Class just to get the public interface. 以下是我想出的内容,但我仍然不希望实例化一个new Class只是为了获取公共接口。 I would like to specify just eventual new public methods. 我只想指定最终的新公共方法。

var Child = function(name, age) {
    var adult = age > 21 ? true : false;

    //return new Class(name);
    var api = new Class(name);
    api.print = function() {
        printDetails();
        return this;
    }
    return api;

    function printDetails() {
        console.log('Child name', name, 'Adult', adult ? 'Yes' : 'No');
    }
};

Child.prototype = Class;
Child.prototype.constructor = Child;

Child.prototype.printDetails = function() {
    console.log('Child name', name, 'Adult', adult ? 'Yes' : 'No');
}

var cls = new Class('Class');
var chd = new Child('Child', 22);

cls.print();
cls.iAmA();
chd.print();
chd.iAmA();

In ES5, having the definition of a base class 在ES5中,具有基类的定义

That's not what we would usually call a class - which would involve instantiation via new and prototype inheritance. 那不是我们通常所说的 -它涉及通过new和原型继承进行实例化。 It's a function returning an object, a factory function . 这是一个返回对象的函数,一个工厂函数

We can still use parasitical inheritance to create new objects with an extended API however. 但是,我们仍然可以使用寄生继承来使用扩展的API创建新对象。

How can I extend it, without instantiate it? 我如何在不实例化的情况下扩展它? How can I inherit the Class public api without redeclaring it? 如何在不重新声明的情况下继承Class公共api?

Just declare a new function that returns the same kind of object: 只需声明一个返回相同类型对象的新函数即可:

function ChildClass(name) {
    return Class(name);
}

Is Child.prototype = Class without new wrong? Child.prototype = Class没有new错误?

Yes. 是。 But it would be wrong with new either - we just don't need the prototype here. 但是,这将是错误的new要么-我们只是不需要原型在这里。

How can I override a private method (and make it callable through public method) 如何覆盖私有方法(并使其可以通过公共方法调用)

You cannot. 你不能。 Private things stay private to the class they are declared in, they cannot be overridden. 私有事物对于声明它们的类保持私有状态,它们不能被覆盖。

I want Child.print() to call Child.printDetails() , instead of Class.printDetails() . 我希望Child.print()调用Child.printDetails()而不是Class.printDetails()

You can however overwrite the public print method to do something different. 但是,您可以覆盖公共print方法以执行其他操作。 You successfully did that in your attempt. 您尝试成功地做到了这一点。

How can I add a method to the api without redeclaring it all 如何在不重新声明所有内容的情况下向api添加方法

Add it to the object you return, no need to copy everything to a new object ("redeclaring"): 将其添加到您返回的对象中,无需将所有内容复制到新对象(“重新声明”):

function ChildClass(name, age) {
    var obj = Class(name);
    obj.newMethod = function() { return age; }
    return obj;
}

The following is what I came up with 以下是我想出的

Yes, your Child function is exactly what it should look like (maybe except for the new in front of Class which you don't need). 是的,您的Child函数确实应该是它的样子(也许除了Class前面的不需要的new函数之外)。

However, you should drop all that prototype stuff (the three assignments) from your code. 但是,您应该从代码中删除所有prototype内容(三个分配)。 Your constructor does not use this anywhere and returns an object, so it's ignored anyway. 您的构造函数不在任何地方使用this函数,而是返回一个对象,因此无论如何都将其忽略。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用私有/受保护/公共字段和方法扩展类 - Extend a class with private/protected/public fields and methods 从javascript类中的“私有”方法访问“公共”方法 - Accessing “Public” methods from “Private” methods in javascript class 在Express和Node.js中,是否可以扩展或覆盖响应对象的方法? - In Express and Node.js, is it possible to extend or override methods of the response object? JS Revealing Module Pattern——通过公共方法访问私有变量 - JS Revealing Module Pattern - access private variables via public methods 如何在 JS 中定义私有方法 Class - How to define private methods in a JS Class 具有私有方法的JS原型类不访问属性 - JS prototype class with private methods not accessing properties RequireJS对象中的私有和公共方法 - Private and public methods in RequireJS objects JavaScript中的私有和公共方法以及变量 - Private and public methods and variable in JavaScript 是否有任何模式可以提供JS中公共静态,私有和公共方法以及var的相似性? - Is there any pattern that provide similarities of public static, private and public methods and vars in JS? @private、@public、@class 和 @param 在 JS 中是什么意思 - what do @private, @public, @class and @param mean in JS
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM