在javascript类中调用super之前调用class函数
我正在尝试用JavaScript扩展请求对象。我的用例是,我想包括更多的方法,并根据在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
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
分支,并将引用正确地撤回到更高的范围(您可以查看我的回答)