为什么这在Node.js
控制台(在4.1.1和5.3.0中进行了测试)中不能运行,而在浏览器中(在Chrome中进行了测试)中却不起作用?该代码块应创建并调用一个记录日志的匿名函数Ok
。
() => {
console.log('Ok');
}()
此外,虽然上述作品中的节点,这并不工作:
n => {
console.log('Ok');
}()
也没有:
(n) => {
console.log('Ok');
}()
奇怪的是,当添加参数时,它实际上会SyntaxError
在立即调用的部分抛出a 。
您需要使它成为函数表达式,而不是不需要名称的函数定义,并使它成为有效的JavaScript。
(() => {
console.log('Ok');
})()
相当于IIFE
(function(){
console.log('Ok')
})();
这可能在Node.js中而不是在chrome中起作用的原因可能是因为其解析器将其解释为自执行函数,因为
function() { console.log('hello'); }();
在Node.js
这是一个函数表达式以及chrome和firefox中可以正常工作,并且大多数浏览器都以这种方式对其进行解释。您需要手动调用它。
告诉解析器期望函数表达式的最广泛接受的方法只是将其包装在parens中,因为在JavaScript中,parens不能包含语句。此时,当解析器遇到function关键字时,它知道将其解析为函数表达式而不是函数声明。
关于参数化版本,这将起作用。
((n) => {
console.log('Ok');
})()
没有括号,所有这些都不起作用。
为什么?
因为根据规范:
- ArrowFunction被列在AssignmentExpression
- CallExpression的LHS必须是MemberExpression,SuperCall或CallExpression
因此,一个ArrowFunction不能在一个的LHS CallExpression。
什么这实际上意味着在如何=>
应解释是,它可以在同一水平排序为赋值运算符=
,+=
等等。
含义
x => {foo}()
没有成为(x => {foo})()
- 解释器尝试将其解释为
x => ({foo}())
- 因此它仍然是一个SyntaxError
因此,解释器确定(
必须输入的错误,并引发SyntaxError
Babel也有一个关于此的错误。
之所以会出现这样的问题,是因为控制台本身试图模仿您当前定位的上下文的全局范围。它还尝试捕获您在控制台中编写的语句和表达式的返回值,以便将其显示为结果。举个例子:
> 3 + 2
< 5
在这里,它好像是一个表达式一样执行,但是您已经把它写成是一个语句。在普通脚本中,该值将被丢弃,但是在这里,必须对代码进行内部处理(例如,将整个语句包装在函数上下文和return
语句中),这会导致各种奇怪的影响,包括您遇到的问题。
这也是脚本中的一些裸露ES6代码可以正常运行,但不能在Chrome Dev Tools控制台中运行的原因之一。
尝试在Node和Chrome控制台中执行此操作:
{ let a = 3 }
在Node或<script>
标签中,它工作正常,但在控制台中,它给出Uncaught SyntaxError: Unexpected identifier
。它还为您提供了到源的链接VMxxx:1
,您可以单击该链接的形式来检查评估的源,其显示为:
({ let a = 3 })
那么为什么要这样做呢?
答案是它需要将您的代码转换成表达式,以便可以将结果返回给调用方并在控制台中显示。您可以通过将语句包装在括号中来做到这一点,使其成为表达式,但也使上面的语句在语法上不正确(表达式不能具有语句块声明)。
控制台确实通过精通代码来尝试解决这些极端情况,但是我认为这超出了此答案的范围。您可以提交一个错误,看看是否可以解决这些问题。
这是一个非常相似的例子:
https://stackoverflow.com/a/28431346/46588
使代码正常工作的最安全方法是确保可以将其作为表达式运行,并检查SyntaxError
源链接以查看实际的执行代码是什么,然后从中反向解决方案。通常,它是指一对战略上放置的括号。
简而言之:控制台尝试尽可能准确地模拟全局执行上下文,但是由于与v8引擎和JavaScript语义的交互的局限性,有时难以解决或无法解决。
我问了这样一个问题:
@getify我有一个问题:要产生#IIFE模式,我们在函数声明周围使用parans将其转换为函数表达式,然后调用它。现在在箭头功能IIFE中,为什么我们需要帕兰斯?默认情况下,箭头功能不是已经是表达式吗?
这就是凯尔·辛普森的答案:
箭头函数是expr,但我们需要在括号中加上“运算符优先级”(sorta),以便最终调用箭头IIFE的括号适用于整个函数,而不仅是函数体的最后一个标记。
x => console.log(x)(4)
与
(x => console.log(x))(4)
-getify(@getify)2020年6月12日
文章标签:arrow-functions , javascript , node.js
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!
评论已关闭!