在c#例如,我可以扩展一个框架类型并为我的类型分配一个表达式,它将保留基类型的所有成员,但也有我的扩展方法。
我试图从Range
继承Sentence
。
注意建议的副本不适用于此处,因为Range
不受这些技术的影响。
我怎样才能在javascript中实现这一目标?我有:
/* Namespace */
var WebPageReader = WebPageReader || {};
/* Classes */
WebPageReader.Sentence = function(range) {
this.setStart(range.startContainer, range.startOffset); // bombs here
this.setEnd(range.endContainer, range.endOffset);
};
function test(){
WebPageReader.Sentence.prototype = new Range();
var dom = new WebPageReader.Dom();
var s = new WebPageReader.Sentence(dom.GetSelectedRange());
alert(s.endOffset) ;
}
WebPageReader.Dom = function() {
/* public methods */
this.GetSelectedRange = function() {
var sel;
if (window.getSelection) {
sel = window.getSelection();
if ((sel.type == "Range" || allowCaretSelection) && sel.rangeCount) {
return sel.getRangeAt(0);
}
}
return null;
}
}
这给出了错误:
未捕获的TypeError:非法调用
尝试#2
当我将代码更改为:
/* Namespace */
var WebPageReader = WebPageReader || {};
/* Classes */
WebPageReader.Sentence = function(range) {
Range.call(this);
};
function test(){
WebPageReader.Sentence.prototype = new Range();
var dom = new WebPageReader.Dom();
var s = new WebPageReader.Sentence(dom.GetSelectedRange());
alert(s.endOffset) ;
}
我收到此错误
未捕获的TypeError:无法构建'范围':请使用' new' 运算符,此DOM对象构造函数不能作为函数调用。
答案 0 :(得分:1)
您没有正确地进行子类化。你应该使用ES6课程。
var WebPageReader = {
Dom: function() {
this.GetSelectedRange = function() {
if (!window.getSelection) return null;
return window.getSelection().getRangeAt(0);
}
},
Sentence: class extends Range {
constructor(range) {
super();
this.setStart(range.startContainer, range.startOffset);
this.setEnd(range.endContainer, range.endOffset);
}
}
};
document.body.addEventListener('click', function() {
var dom = new WebPageReader.Dom();
var s = new WebPageReader.Sentence(dom.GetSelectedRange());
console.log(s.endOffset);
});

Select text

它有效,因为super()
将实例初始化为真实的Range
。在ES5中,您只能执行从Range.prototype
继承实例的操作,这不足以成为真正的Range
实例。 Range
方法只能在真实Range
个实例上调用。
答案 1 :(得分:1)
内置JavaScript类,例如Error
,Array
或Range
cannot be subclassed using only ES5 features。在支持从Range
扩展的ES6类的浏览器中可能工作,但这仍然是一个脆弱的事情,我觉得在这种情况下这样做是合理的。我认为你只需要辅助方法,而不是子类化。您可以使用function bind syntax operator:
// Would have been written
Sentence.prototype.additionalOperation = function() {
return this.endContainer ...;
}
// can write this:
function additionalOperation() {
return this.endContainer ...
}
// usage
// instead of:
new Sentence(range).additionalOperation();
// use this:
additionalOperation.call(range);
// or with bind syntax:
range::additionalOperation();