【发布时间】:2016-05-21 15:12:37
【问题描述】:
在 es2015 中,如果我有一个基类来表示一个看起来像这样的List:
class List {
constructor(data){
this.data = data
}
sortBy(attribute){
return this.data.sort((a,b) => {
return (a[attribute] < b[attribute]) ? 1 : -1;
})
}
get count() { return this.data.length }
}
然后我可能想用一种不太通用的数据子类化该基类,即,如果我是一个精灵,玩具:
class ToyList extends List {
constructor(toys){
super(toys);
this.toys = toys;
}
}
此时ToyList 与List 没有区别,只是名称不同。但是,如果您查看ToyList 的实例化,它同时具有data 和toys 属性。它们指的是同一个数组,就概念化ToyList 的点而言,data 没有多大意义。
如果我创建ToyList,我同时拥有.data 和.toys 属性:
tl = new ToyList(['truck', 'plane', 'doll'])
Object { data: Array[3], toys: Array[3] }
那么我的tl 有一个data 和一个toys 属性。它们都是对同一个数组的引用,但我希望子类只有有toys 引用。
这是另一个使用基类方法的示例:
class Todos extends List {
constructor(todos){
super(todos);
this.todos = todos;
}
get byPriority(){
return this.todos.sortBy('priority')
}
}
var thingsToDo = [
{task: 'wash the dog', priority: 10},
{task: 'do taxes', priority: 1},
{task: 'clean the garage', priority: 0}
]
var todos = new Todos(thingsToDo);
todos.byPriority
这很好,因为这样我就可以参考.byPriority 来获取列表的排序版本,该版本非常特定于这种特定类型的数据。但我不知道我怎么能做到这一点,因为
但我得到的是:
TypeError: this.todos.sortBy is not a function
总而言之,我想要一种方法来引用具有特定于子类语义的名称的基类属性,而不会丢失基类的方法。
【问题讨论】:
-
好吧,如果您不想要 List 提供的功能,为什么要从 List 继承呢?似乎您的抽象需要重新评估!?
-
我在基类中添加了更多方法以使要点更清楚。当然,Collection 上还有其他方法,例如您可以对 Backbone 集合执行的各种操作(排序、搜索、保存等)。我的问题是如何覆盖基类上的给定属性,以便派生类可以具有特定于域的方法和属性,仅此而已。
-
没有反对在派生类上添加附加功能。但是一旦你不将你的集合应用到
data-property,List 的所有附加功能都会失败,你必须为派生类包装或重新实现它们;就像您使用get toyCount()而不是使用get count()一样。整个方法没有意义,只会增加复杂性。我将添加一个更好方法的示例。 -
But what I get is: TypeError: this.todos.sortBy is not a functionsortBy 是您的 List 类的方法,但 this.todos 不是 List,它是 Todos 类和数组类型的私有属性,它不实现您的方法。这正是我正在谈论的问题。您必须在 Todos 上重新实现 sortBy 函数以对 todos 属性而不是数据属性进行排序,等等……对于您编写的每个子类。看看我的答案,我写了一个示例代码,可以解决整个问题。
标签: javascript class inheritance ecmascript-6