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

May*_*nty 3 javascript async-await typescript

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

\n\n
async function hello() {\n  return arguments;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

当 TypeScript 的编译目标设置为es3或时es5,上述文件无法编译,并出现以下错误:

\n\n
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.\n\n2   return arguments;\n           ~~~~~~~~~\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是,如果使用更高的编译目标(我已经测试过es2017esnext,则不会出现错误。

\n\n
\n\n

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

\n\n

一些注意事项:

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

我的假设

\n\n

我怀疑因为Promise需要在es3and中进行polyfill es5,所以polyfill无法支持arguments,因为它依赖于函数被调用者。

\n\n

进一步阅读:ES5.1 Spec \xc2\xa7 10.6 Arguments 对象

\n

Sha*_*son 6

这是因为异步函数被转换为生成器的基本填充实现;这个实现基本上交换了函数的主体以将其包装在另一个函数中,因此任何使用都arguments永远不会访问argumentshello 的原始内容,而是__generator

下面是一个例子,其中 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*/];
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

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