javascript - TypeScript:异步函数中的参数关键字

标签 javascript typescript async-await

考虑我在我的一个项目中注意到的以下奇怪行为:

async function hello() {
  return arguments;
}

当 TypeScript 的编译目标设置为 es3es5 时,上述文件编译失败并出现以下错误:

error TS2522: The 'arguments' object cannot be referenced in an async function or method in ES3 and ES5. Consider using a standard function or method.

2   return arguments;
           ~~~~~~~~~

但是,使用更高的编译目标(我已经测试过 es2017esnext)没有错误。


当 TypeScript 的编译目标设置为 es3es5 时,arguments 关键字如何阻止它在异步函数中使用?

一些注意事项:

  • 在现代 JavaScript 中复制时,此函数不会抛出异常
  • 此行为只能在async 函数中复制

我的假设

我怀疑是因为Promise需要在es3es5中进行polyfill,polyfill不支持arguments因为它依赖于函数调用者。

进一步阅读:ES5.1 Spec § 10.6 Arguments Object

最佳答案

这是因为异步函数被转译为生成器的基本 polyfill 实现;这个实现基本上交换了你的函数的主体以将它包装在另一个函数中,因此任何使用 arguments 都将永远不会访问 hello 的原始 arguments 而不是 __生成器

下面是一个这样的例子,其中 hello 不接受参数并生成以下内容,其中函数体被另一个函数包装。

async function hello() {
    console.log(arguments);
} // becomes.....


function hello() {
    return __awaiter(this, arguments, void 0, function () {
        return __generator(this, function (_a) {
            console.log(arguments);
            return [2 /*return*/];
        });
    });
}

重申一下,console.log(arguments) 已经从 hello 的上下文移动到 __generator 的上下文,这意味着它永远不会像您期望的那样运行。如果您的目标是现代浏览器(非 IE),您可以将编译目标设置为 ES6+,在这种情况下,此限制将被删除。

关于javascript - TypeScript:异步函数中的参数关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56798016/

相关文章:

angular - 使 Electron 应用程序允许从本地文件系统下载pdf文件

javascript - Node.js mongodb 驱动程序异步/等待查询

javascript - 执行跳过 promise 语句

typescript - Typescript 中命名元组的通用名称是什么?

typescript - TypeScript中有没有类似于 `valueof`的 `keyof`?

c# - 如何使用带有 CancellationToken 的任务包装单个同步操作?

javascript - 输入 type=number 但添加字母后缀

javascript - 从 laravel Controller 将值传递给 ajax 然后获取特定字段

javascript - 禁用鼠标事件 react

javascript - 通过代理服务器请求 http 调用