为什么在获取响应上使用解构分配会导致.json()方法消失?

JSa*_*ger 2 javascript ecmascript-6 fetch-api

感谢您抽出宝贵的时间查看此内容。我遇到了一些意外的行为,在aws lambda中工作时无法弄清楚。

我正在执行一个访存,然后根据其成功还是失败做一些不同的事情,如果一切都顺利,最终希望使用fetch.json()方法。我正在使用await使lambda处理程序的内部“同步”。

当我将获取的结果分配给一个变量然后检查它时,一切都很好。但是我喜欢整洁的代码,所以我决定使用解构分配,突然事情开始崩溃。

为了说明我的困惑,我提供了一个代码段,该代码段重复了该问题并显示了五种不同的内容-前两项工作,其余部分休息。

在第三个示例中,“ r”是一个空对象。其余的运算符将其破坏,我不理解。它是在创建一个新对象并拒绝复制属性吗?销毁时属性不存在吗?如果是这样,为什么还可以正确地破坏状态?

四只是三者问题的简化示例。

五也让我感到困惑,因为我能够获取json方法,但是当我尝试执行它时,它抛出了非法调用异常。

摘录如下:

const one = async () => {
  const r = await fetch('https://reqres.in/api/users?page=2');
  console.log(await r.json());
}

const two = async () => {
  const r = await fetch('https://reqres.in/api/users?page=2');
  const { ok } = r;
  console.log(await r.json());
  console.log(ok);
}

const three = async () => {
  const { ok, status, ...r } = await fetch('https://reqres.in/api/users?page=2');
  try {
    console.log(await r.json());
  } catch (e) {
     console.log(e);
     console.log(ok);
     console.log(status);
     console.log(r);
  }
}

const four = async () => {
  const { ...r } = await fetch('https://reqres.in/api/users?page=2');
  console.log(r);
}

const five = async () => {
  const { json } = await fetch('https://reqres.in/api/users?page=2');
  try {
    console.log(await json());
   } catch (e) {
    console.log(e);
    console.log(json);
   }
}

[one, two, three, four, five].forEach(f => f());
Run Code Online (Sandbox Code Playgroud)

感谢你的宝贵时间。

注意:由于某种原因,SO会将异常记录为空对象,所以这是一个小提琴:https : //jsfiddle.net/ygbm6kwq/4/

编辑:在示例二中意外遗漏了一行,代码段和小提琴已更新。

Ber*_*rgi 5

其余的运算符将其破坏,我不理解。它是在创建一个新对象并拒绝复制属性吗?

是的,就是这样。属性rest元素创建一个新对象,并将所有剩余的可枚举的自身属性复制到该对象中。但是新r对象将是一个普通对象,而不是Response实例,因此它不会继承.json()方法。

我能够获取json方法,但是当我尝试执行该方法时,它将引发非法调用异常。

是的,这是一种方法。因此,必须在实例上以适当的this值调用它。您可以从技术上做到

const response = await fetch('https://reqres.in/api/users?page=2');
const { json } = response;
console.log(await json.call(response));
Run Code Online (Sandbox Code Playgroud)

甚至没有进行任何破坏,Response.prototype.json.call(response)但这毫无意义。