2017-07-12 40 views
1

ES5,有一个基类,提供一个公共的API定义:扩展和覆盖JS类的私人和公共方法

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 wron G?我只想定义类和继承,而不是实例化任何类。

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

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

  • 继承类的公共API不重新声明它

    我可以return new Class(name)儿童,但我不会被称为我的新儿童方法(方法被调用,而不是)

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

回答

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功能正是它应该看起来的样子(除了你不需要的Class前的new除外)。

但是,您应该从代码中删除所有prototype材料(三个作业)。你的构造函数不会在任何地方使用this并返回一个对象,所以它仍然被忽略。