简体   繁体   English

如何在JavaScript中的内置JavaScript类的子类中使用基类方法

[英]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类(例如ErrorArrayRange 不能仅使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM