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

在javascript类中调用super之前调用class函数,javascript,ecmascript-6,Javascript,Ecmascript 6,我正在尝试用JavaScript扩展请求对象。我的用例是,我想包括更多的方法,并根据httpMethod修改URL 我尝试了以下方法: class ServiceRequest extends Request { constructor(config) { const url = config && config.url; const method = config && config.method; const body = conf

我正在尝试用JavaScript扩展请求对象。我的用例是,我想包括更多的方法,并根据
httpMethod
修改URL

我尝试了以下方法:

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;}
}
现在它是给错误没有超级我不能称之为这个。我这里的问题是url是只读的,所以我不能先调用super。如果我先调用super,则无法重新分配url


关于如何使其工作的一些建议?

由于请求API大多是只读的,因此更好的方法可能是围绕请求对象创建类包装,而不是扩展它,如下所示:

类服务请求{
构造函数(配置){
const url=config&&config.url;
const method=config&&config.method;
const body=config&&JSON.stringify(config.body | |{})//将其更改为{}也应字符串化
const headers=(config&&config.headers)| |新头({
“内容类型”:“应用程序/json;字符集=UTF-8”,
接受:'application/json',
});
让apiUrl=url;//apiUrl应该在if语句之外,以避免出错
if(url&方法){
apiUrl=this.buildAPIPath(url,方法);
}
this.request=新请求(apirl,{method,body,headers});
}
buildAPIPath(url,httpmethod){
//所有url修改返回修改url;
}
}
我试图在JavaScript中扩展
请求
对象

绝对没有理由这样做-您没有覆盖它的任何方法。只需编写一个普通函数,返回一个普通的
请求

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});
}
在调用super之前,我不能调用这个类函数,这是一个错误


对。在
super
调用之前,不存在任何实例,因此不能对其调用任何方法。真的没办法。但是您的
buildAPIPath
方法无论如何都不使用实例,因此它不应该是一个方法。您可以在
类之外使用普通函数声明,或者使用静态方法(可以使用
new.target.buildapath(…)
ServiceRequest.buildapath(…)
)。

super
之前无法访问此
类实例,因为ES6类是这样设计的,而且没有解决办法。若需要这样做,那个么ES6类应该被分解为并没有这个限制的常规构造函数

事实并非如此,因为
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});
  }
}

当继承开始时,它变得相当混乱。你试过使用对象/函数组合吗?没有。你能详细说明更多的对象/函数组合吗。可能是不相关的,但仍然可能是拼写错误修复
const body=config&&JSON.stringify(config.body |{})好吧,如果您还没有深入到开发阶段,并且在代码中使用了“继承”,那么在JS中尝试函数式编程就不算太远了。你可以从开始,我知道这不是你问题的解决方案,但它是另一个视角。谢谢@karengrigoryan什么是“类包装器”?您在代码中更改了什么?您为什么不处理
新请求
?为什么您在
extend
ed类中仍然使用
this
而没有
super
调用?@Bergi这是一个打字错误,我忘了删除
extends
部分。谢谢你的观察。好的,这解决了我最后的问题,但没有解决其他问题。@Bergi更新了更多的解释和另一个拼写错误修正,谢谢你的宝贵意见。我不明白你的“常用配方”。为什么不直接调用
buildAPIPath
?另外,如果您在
ServiceRequest
上调用(任一)方法,将永远不会使用覆盖。如果需要覆盖子类中的buildAPIPath,这会阻止ServiceRequest进一步扩展。在我看来,这是静态buildAPIPath方法唯一的缺点,我刚刚解决了它。我有很多案例(主要是第三方LIB),我不得不复制并粘贴一个类,因为开发人员没有想到有人可以从扩展它中获益。我仍然不明白。您是否在代码段中设计了
ServiceRequest
类以便对其进行扩展,如果是,如何进行扩展?另外,
\u buildAPIPath
buildappath
之间的区别是什么?
类FooServiceRequest扩展了ServiceRequest{static buildAPIPath(…){…}
。如果直接在构造函数中调用
ServiceRequest.buildAPIPath(…)
,则不可能。我很确定我在别人的代码中遇到了这个解决方案,所以我并没有发明它。把它和我的另一个案子混在一起了,谢谢你的注意。至于new.target transfilation,扩展内置函数的类无论如何都会导致问题。为什么在您的解决方案中也使用
JSON.stringify(config.body)
,但将默认值
{}
保留为对象?你为什么决定跳过
if(url&&method){
逻辑分支?这一变化的解释在哪里?@KarenGrigoryan我只是保留了OPs代码中的
const body
行,甚至没有查看它的功能。跳过
if(url&&method)
检查对于将
apiUrl
放置在正确的范围内是必要的,该范围可用于返回的
新请求
调用。我不知道当条件不满足时该怎么办,可能会出现异常。1.无论如何,这是答案中的潜在错误,不管您如何感知和反应o it.2.您在回答中没有提到,您故意决定删除
if
分支。3.此外,没有必要删除
if
分支,因为您仍然可以拥有
if
分支,并将引用正确地撤回到更高的范围(您可以查看我的回答)