简体   繁体   English

在javascript类中调用super之前先调用类函数

[英]Call class function before calling super in javascript class

I am trying to extend Request object in JavaScript. 我正在尝试扩展JavaScript中的Request对象。 My use case is that I want to include some more methods and modify URL according to httpMethod . 我的用例是我想包含更多方法并根据httpMethod修改URL。

I have tried like the following: 我已经尝试过如下所示:

class ServiceRequest extends Request {
  constructor(config) {
    const url = config && config.url;
    const method = config && config.method;
    const body = config && (JSON.stringify(config.body) || {});
    const headers = (config && config.headers) || new Headers({
      'Content-Type': 'application/json; charset=UTF-8',
      Accept: 'application/json',
    });
    if (url && method) {
      const apiUrl = this.buildAPIPath(url, method);
    }
    super(apiUrl, {method,body,headers});
  }
  buildAPIPath (url, httpmethod) {// all the url modifications return modify url;}
}

Now it is giving error without super I can not call this. 现在它给错误没有超级我不能称之为。 My problem here is that the url is read only, so I cannot call super first. 我的问题是网址是只读的,因此我不能先调用super。 If I call super first then I cannot reassign url. 如果我先调用超级,则无法重新分配网址。

Some suggestions on how I can make it work? 关于如何使其工作的一些建议?

I am trying to extend Request object in JavaScript. 我正在尝试扩展JavaScript中的Request对象。

There's absolutely no reason to do that - you're not overwriting any of its methods. 绝对没有理由这样做-您不会覆盖其任何方法。 Just write a normal function that returns a normal Request : 只需编写一个返回正常Request的普通函数:

function buildAPIPath (url, httpmethod) {
  // all the url modifications
  return /* modified url */;
}
export function ServiceRequest(config) {
  const url = config && config.url;
  const method = config && config.method;
  const body = config && JSON.stringify(config.body || {});
  const headers = (config && config.headers) || new Headers({
    'Content-Type': 'application/json; charset=UTF-8',
    Accept: 'application/json',
  });
  const apiUrl = buildAPIPath(url, method);
  return new Request(apiUrl, {method,body,headers});
}

It is giving error I can not call this class function before calling super 给出错误,我无法在调用super之前调用此类函数

Yes. 是。 Before the super call, no instance exists, so you cannot call any methods on it. super调用之前,不存在任何实例,因此您无法在其上调用任何方法。 There's really no way around this. 真的没有办法解决这个问题。 But your buildAPIPath method does not use an instance anyway, so it should not be a method at all. 但是您的buildAPIPath方法buildAPIPath使用实例,因此它根本不应该是一个方法。 You would use a plain function declaration outside of the class , or a static method (which you could call with new.target.buildAPIPath(…) or ServiceRequest.buildAPIPath(…) ). 您可以在class之外使用普通的函数声明,也可以使用静态方法(可以使用new.target.buildAPIPath(…)ServiceRequest.buildAPIPath(…)调用)。

this class instance cannot be accessed before super because ES6 classes were designed this way, and there's no workaround. this类实例不能被访问之前super因为ES6类被设计成这样,而且也没有解决办法。 If there's a need to do that, ES6 class should be desugared to regular constructor function that doesn't have this limitation. 如果有必要这样做,则应将ES6类简化为没有此限制的常规构造函数。

This is not the case, because buildAPIPath doesn't involve class instance, so it can be static method: 事实并非如此,因为buildAPIPath不涉及类实例,因此它可以是静态方法:

class ServiceRequest extends Request {
  static buildAPIPath(url, httpmethod) {
    /* ... */   
  }

  constructor(config) {
    /* ... */
    if (url && method) {
      apiUrl = new.target.buildAPIPath(url, method);
    }
    super(apiUrl, {method,body,headers});
  }
}

Since Request API is mostly read-only, the better approach may be to create a class wrapper around Request object, instead of extending it, something like this: 由于Request API主要是只读的,更好的方法可能是围绕Request对象创建一个类包装,而不是扩展它,如下所示:

 class ServiceRequest { constructor(config) { const url = config && config.url; const method = config && config.method; const body = config && JSON.stringify(config.body || {}); // changed this as {} should also be stringified const headers = (config && config.headers) || new Headers({ 'Content-Type': 'application/json; charset=UTF-8', Accept: 'application/json', }); let apiUrl = url; // apiUrl should be outside if statement, to not error out if (url && method) { apiUrl = this.buildAPIPath(url, method); } this.request = new Request(apiUrl, {method,body,headers}); } buildAPIPath (url, httpmethod) { // all the url modifications return modify url; } } 

And later use it with fetch like this: 然后将其与fetch一起使用,如下所示:

 const {request} = new ServiceRequest({/*opts*/}) fetch(request); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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