Javascript ES6立即调用了arrow函数
为什么这在Node.js控制台(在4.1.1和5.3.0中测试)中有效,但在浏览器(在Chrome中测试)中无效 此代码块应创建并调用记录Javascript ES6立即调用了arrow函数,javascript,node.js,arrow-functions,Javascript,Node.js,Arrow Functions,为什么这在Node.js控制台(在4.1.1和5.3.0中测试)中有效,但在浏览器(在Chrome中测试)中无效 此代码块应创建并调用记录Ok的匿名函数 () => { console.log('Ok'); }() 此外,尽管上述在Node.js中起作用,但这不起作用: n => { console.log('Ok'); }() 这也不是: (n) => { console.log('Ok'); }() 奇怪的是,当添加参数时,它实际上会在立即调用的部分抛出一
Ok
的匿名函数
() => {
console.log('Ok');
}()
此外,尽管上述在Node.js中起作用,但这不起作用:
n => {
console.log('Ok');
}()
这也不是:
(n) => {
console.log('Ok');
}()
奇怪的是,当添加参数时,它实际上会在立即调用的部分抛出一个
SyntaxError
。您需要将其设置为函数表达式,而不是函数定义,该定义不需要名称,并使其成为有效的JavaScript
(() => {
console.log('Ok');
})()
相当于
这在Node.js中起作用而在Chrome中不起作用的可能原因是其解析器将其解释为一个自执行函数,如下所示
function() { console.log('hello'); }();
在Node.js中运行良好。这是一个函数表达式,Chrome和Firefox以及大多数浏览器都是这样解释的。您需要手动调用它
告诉解析器期望函数表达式的最广为接受的方法就是将其包装在parens中,因为在JavaScript中,parens不能包含语句。此时,当解析器遇到function关键字时,它知道将其解析为函数表达式,而不是函数声明
对于参数化版本
,这将起作用
((n) => {
console.log('Ok');
})()
如果没有括号,这些都不应该起作用 为什么? 因为根据规范:
这在解释
=>
时有效地意味着,它与赋值运算符=
,+=
等在同一级别上工作
意义
不会变成x=>{foo}()
(x=>{foo})(
- 解释器试图将其解释为
x=>({foo}())
- 因此,它仍然是一个语法错误
- 因此,解释器判断
一定是错误的,并抛出一个语法错误(
Babel上也有一个bug。您之所以会看到这样的问题,是因为控制台本身试图模拟当前目标上下文的全局范围。它还试图捕获您在控制台中编写的语句和表达式的返回值,以便将结果显示出来。例如:
> 3 + 2
< 5
在节点或
标记中,它工作正常,但在控制台中,它提供了未捕获的SyntaxError:意外标识符
。它还以VMxxx:1
的形式提供了指向源的链接,您可以单击该链接来检查已评估的源,该链接显示为:
({ let a = 3 })
那么它为什么要这样做呢
答案是,它需要将代码转换为表达式,以便将结果返回给调用方并显示在控制台中。可以通过将语句括在括号中来实现这一点,这使其成为表达式,但也会使上面的块在语法上不正确(表达式不能有块声明)
控制台确实试图通过对代码进行智能化来修复这些边缘情况,但这超出了这个答案的范围,我想,您可以提交一个bug来查看这是否是他们考虑修复的东西。 下面是一个非常相似的例子:
使代码正常工作的最安全的方法是确保它可以作为表达式运行,并检查SyntaxError
源链接,查看实际执行的代码是什么,然后从中反向设计解决方案。通常这意味着一对策略性放置的括号
简而言之:控制台试图尽可能准确地模拟全局执行上下文,但由于与v8引擎和JavaScript语义交互的限制,这有时很难或不可能解决。我问了一个类似的问题: @getify我有一个问题:为了生成一个#iLife模式,我们在函数声明周围使用Paran将其转换为函数表达式,然后调用它。现在在arrow函数IIFEs中,为什么我们需要Paran?!arrow函数在默认情况下不是已经是表达式了吗 这是凯尔·辛普森的回答: arrow函数是一个表达式,但我们需要“运算符优先级”(sorta)的周围参数b/c,以便调用arrow IIFE的最终参数应用于整个函数,而不仅仅是其主体的最后一个标记 vs
-getify(@getify)第一个示例在
Node.js中工作,并且实际记录了值。我的问题是为什么它工作?为什么我添加参数时它不工作?我非常熟悉IIFE
s,知道如何修复我的代码。我只是好奇为什么,例如,添加n
参数时,我的IIFE
不工作,e即使它没有参数也能工作。我没有否决,但问题是为什么参数化版本在节点中不工作,而完全相同的定义没有参数——这并不是问匿名函数的节点/浏览器实现之间的区别,这是一个好消息,但它没有回答问题,如前所述before,-当没有参数的完全相同的定义不起作用时,为什么参数化版本在节点中不起作用?但是什么是function(){}()
在arrow函数中?如果我想让函数对象公开的函数表达式避免这种情况。问得好。两个参数化版本都能与BabelOut一起工作,那么(n=>{console.log(“Ok”);})(;
是否有效?是(n=>{console.log(“Ok”);})()
甚至可以在Chrome开发控制台上运行,因此,3年后,答案是?下面3个答案中的一个肯定应该被接受?!@joedotnot我没有得到一个cle
{ let a = 3 }
({ let a = 3 })
x => console.log(x)(4) // trouble
(x => console.log(x))(4) // working