[英]How to use base class methods in a subclass of a Builtin JavaScript class in javascript
In c# for example I can extend a framework type and assign an expression to my type and it will retain all the members of the base type but also have my extended methods. 例如,在c#中,我可以扩展框架类型并为我的类型分配一个表达式,它将保留基本类型的所有成员,但也具有我的扩展方法。
I'm trying to inherit Sentence
from Range
. 我正在尝试从Range
继承Sentence
。
Note the suggested duplicate doesn't apply here because Range
is not susceptible to these techniques. 请注意 ,此处建议的副本不适用于此处,因为Range
不受这些技术的影响。
How can I achieve this in javascript? 如何在javascript中实现呢? I have: 我有:
/* 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;
}
}
This gives the error: 这给出了错误:
Uncaught TypeError: Illegal invocation 未捕获的TypeError:非法调用
Attempt #2 尝试#2
When i change my code to this: 当我将代码更改为此:
/* 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) ;
}
I get this error 我得到这个错误
Uncaught TypeError: Failed to construct 'Range': Please use the 'new' operator, this DOM object constructor cannot be called as a function. Uncaught TypeError:无法构造'Range':请使用'new'运算符,此DOM对象构造函数不能作为函数调用。
You are not subclassing properly. 您没有正确子类化。 You should use ES6 classes. 您应该使用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
It works because super()
initializes the instance as a real Range
. 之所以有效,是因为super()
将实例初始化为实际的Range
。 In ES5 you can only do things like making the instance inherit from Range.prototype
, which is not enough to be a real Range
instance. 在ES5中,您只能执行使实例继承自Range.prototype
,而这不足以成为真正的Range
实例。 And Range
methods can only be called on real Range
instances. 而且Range
方法只能在实际的Range
实例上调用。
Builtin JavaScript classes such as Error
, Array
or Range
cannot be subclassed using only ES5 features . 内置的JavaScript类(例如Error
, Array
或Range
不能仅使用ES5功能进行子类化 。 In browsers that support ES6 classes extending from Range
might work, but this is a fragile thing yet, and I dot't feel doing so is justified in this case. 在支持从Range
扩展到ES6类的浏览器中, 可能会起作用,但这是一件脆弱的事情,在这种情况下,我觉得这样做是没有道理的。 I think you only need helper methods, not subclassing. 我认为您只需要辅助方法,而无需子类化。 You could achive similar looks by using the 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();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.