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

时间:2017-07-12 14:56:04

标签: javascript oop inheritance ecmascript-5 override

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);
    };
};

我怎么能:

  • 扩展它,而不实例化

    Child.prototype = Class没有new错误吗?我只想定义类和继承,而不是实例化任何类。

  • 覆盖私有方法(并通过公共方法使其可调用)

    我希望 Child.print()调用 Child.printDetails(),而不是 Class.printDetails()

  • 继承Class public api而不重新声明

    我可以从 Child return new Class(name),但我不会调用我的新 Child 方法( Class 方法被称为而不是被覆盖的那些)

  • 向api添加方法而不重新声明所有

    我不知道是否有可能,但我的目标是尽可能地继承并定义添加/变化。

以下是我提出的内容,但我仍然不想实例化new Class只是为了获取公共接口。我想指定最终的新公共方法。

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();

1 个答案:

答案 0 :(得分:0)

  

在ES5中,具有基类的定义

这不是我们通常所说的 - 这将涉及通过new实例化和原型继承。它是一个返回对象的函数,一个工厂函数

我们仍然可以使用parasitical inheritance来创建具有扩展API的新对象。

  

如何在不实例化的情况下扩展它?   如何在不重新声明的情况下继承Class public api?

只需声明一个返回相同类型对象的新函数:

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

Child.prototype = Class没有new错误吗?

是。但new也是错误的 - 我们在这里不需要原型。

  

如何覆盖私有方法(并通过公共方法使其可调用)

你做不到。私人事物对于他们所宣称的阶级保持私密,他们不能被覆盖。

  

我希望Child.print()拨打Child.printDetails(),而不是Class.printDetails()

但是,您可以覆盖公共print方法来执行不同的操作。你成功地尝试了这一点。

  

如何在不重新声明所有内容的情况下向api添加方法

将其添加到您返回的对象中,无需将所有内容复制到新对象("重新声明"):

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

以下是我提出的内容

是的,您的Child功能正是它的样子(可能除了您不需要的new前面的Class)。

但是,您应该从代码中删除所有prototype内容(三个分配)。你的构造函数不会在任何地方使用this并返回一个对象,所以它无论如何都会被忽略。