如何用Ecmascript 6类扩展对象文字类
我有一个基class
被定义为一个object literal
,在构造函数的作用域内定义的方法。 喜欢这个:
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类的原型上(就像你一直以来那样)。
如果你在构造函数中定义了它们,并将它们创build为实例属性(它影响从原型inheritance的任何东西),那么在覆盖它们时就必须这样做:
class SomeMapping extends NodeMappingAbstract{ constructor(){ super(); this.mapToContent = function(rawElement) { console.warn('mapContent called'); return rawElement; }; } }
这里的问题是你直接将方法附加到NodeMappingAbstract
( this
)的实例上,而不是函数的prototype
。
当JavaScript执行一个对象属性的查找时,它首先检查这些对象的直接属性,这些属性当你给this
属性赋值的时候是可用的。 只有当它没有find那种立即可用的财产时,它才会转向prototype
。 所以,尽pipe你扩展了NodeMappingAbstract
并且在prototype
上定义了方法(通过class
糖),但是实际上并没有在NodeMappingAbstract
重写实例化的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); };