如何使用 Ecmascript 6 classes 扩展对象字面量 class
How to extend an object literal class with Ecmascript 6 classes
我有一个定义为 object literal
的基础 class
,其方法定义在构造函数的范围内。像这样:
var NodeMappingAbstract = function NodeMappingAbstract() {
this.mapToContent = function (obj) {
throw new Error('Not implemented');
};
this.getInfo = function (data) {
throw new Error('Not implemented');
};
this.normalizeUri = function normalizeUri(uri) {
return uriNormalizer.normalize(uri);
};
};
如何使用 ES6 class
语法扩展 NodeMappingAbstract
?我尝试使用 extends
和 super()
:
class SomeMapping extends NodeMappingAbstract{
constructor(){
super();
}
mapToContent(rawElement) {
console.warn('mapContent called');
return rawElement;
}
}
但是当我实例化它并像这样调用 mapToContent
时:
let m = new SomeMapping();
m.mapToContent();
我得到Error: Not implemented
,这意味着使用了NodeMappingAbstract
的实现。
你应该把你的方法放在你的 ES5 原型上 class(你总是应该这样做)。
如果您在构造函数中定义它们,并将它们创建为实例属性(隐藏从原型继承的任何内容),则在覆盖它们时必须执行相同的操作:
class SomeMapping extends NodeMappingAbstract{
constructor(){
super();
this.mapToContent = function(rawElement) {
console.warn('mapContent called');
return rawElement;
};
}
}
这里的问题是您将方法直接附加到 NodeMappingAbstract
(this
) 的实例,而不是函数的 prototype
。
当 JavaScript 执行对象查找 属性 时,它首先检查对象直接拥有的属性,这些属性在您将某些内容分配给 this
时可用。只有当它没有发现 属性 以这种方式立即可用时,它才会转向 prototype
。因此,虽然您正在扩展 NodeMappingAbstract
并在 prototype
上定义方法(通过 class
糖),但您实际上并没有覆盖分配给 this
的属性NodeMappingAbstract
.
中的实例化
因此,将方法声明移到函数体之外并移至其 prototype
:
var NodeMappingAbstract = function NodeMappingAbstract () {};
NodeMappingAbstract.prototype.mapToContent = function (obj) {
throw new Error('Not implemented');
};
NodeMappingAbstract.prototype.getInfo = function (data) {
throw new Error('Not implemented');
};
NodeMappingAbstract.prototype.normalizeUri = function normalizeUri (uri) {
return uriNormalizer.normalize(uri);
};
我有一个定义为 object literal
的基础 class
,其方法定义在构造函数的范围内。像这样:
var NodeMappingAbstract = function NodeMappingAbstract() {
this.mapToContent = function (obj) {
throw new Error('Not implemented');
};
this.getInfo = function (data) {
throw new Error('Not implemented');
};
this.normalizeUri = function normalizeUri(uri) {
return uriNormalizer.normalize(uri);
};
};
如何使用 ES6 class
语法扩展 NodeMappingAbstract
?我尝试使用 extends
和 super()
:
class SomeMapping extends NodeMappingAbstract{
constructor(){
super();
}
mapToContent(rawElement) {
console.warn('mapContent called');
return rawElement;
}
}
但是当我实例化它并像这样调用 mapToContent
时:
let m = new SomeMapping();
m.mapToContent();
我得到Error: Not implemented
,这意味着使用了NodeMappingAbstract
的实现。
你应该把你的方法放在你的 ES5 原型上 class(你总是应该这样做)。
如果您在构造函数中定义它们,并将它们创建为实例属性(隐藏从原型继承的任何内容),则在覆盖它们时必须执行相同的操作:
class SomeMapping extends NodeMappingAbstract{
constructor(){
super();
this.mapToContent = function(rawElement) {
console.warn('mapContent called');
return rawElement;
};
}
}
这里的问题是您将方法直接附加到 NodeMappingAbstract
(this
) 的实例,而不是函数的 prototype
。
当 JavaScript 执行对象查找 属性 时,它首先检查对象直接拥有的属性,这些属性在您将某些内容分配给 this
时可用。只有当它没有发现 属性 以这种方式立即可用时,它才会转向 prototype
。因此,虽然您正在扩展 NodeMappingAbstract
并在 prototype
上定义方法(通过 class
糖),但您实际上并没有覆盖分配给 this
的属性NodeMappingAbstract
.
因此,将方法声明移到函数体之外并移至其 prototype
:
var NodeMappingAbstract = function NodeMappingAbstract () {};
NodeMappingAbstract.prototype.mapToContent = function (obj) {
throw new Error('Not implemented');
};
NodeMappingAbstract.prototype.getInfo = function (data) {
throw new Error('Not implemented');
};
NodeMappingAbstract.prototype.normalizeUri = function normalizeUri (uri) {
return uriNormalizer.normalize(uri);
};