为什么function a(b){alert(b)}(1) 不会报错
当在函数声明之后直接加括号,如下
function a(){
alert(1)
}()
会报 Unexpected token 错误,查阅了资料后知道函数声明之后是不能直接加括号执行的,需要将函数声明转化为函数表达式。如下:
!function a(){alert(1)}() // true ,(也可以将!换成 +、-、~ 中的任一个)。
(function a(){alert(1)})() // undefined
(function a(){alert(1)}()) // undefined
当我试着写了如下代码时:
function a(b){alert(b)}(1) // 1
alert(a) // function a(b){alert(b)}
为什么第一行代码会在控制台输出 1? 第二行代码会弹出 function a(b){alert(b)}?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是个有意思的问题,尝试分析下。
在 ECMAScript 中,函数声明 (Function declaration, FD)与 具名函数表达式(Named function expresson, NFE)具有相同的语法:
function a(b) {alert(b)}
到底是一个 FD 还是一个 NFE 取决于它所处的位置,例如在 IIFE 结构(function a(b) {alert(b)})()
中,函数被包裹在分组运算符()
中,此时该函数就是一个 NFE,因为分组运算符只接受表达式。把函数放在!
,+
,!
,void
等运算符后面也是同理,明确地表示该函数是一个 NFE。相反,当
function a(b) {alert(b)}
出现在语句开头的时候,它就被解析为一个 FD,而不是 NFE。因此,function a(b){alert(b)}(1)
被解析为两条语句:console 显示的
1
是(1)
求值的结果。(你可以把function a(b){alert(b)}(1)
复制到JavaScript AST visualizer 查看生成的抽象语法树)alert(a)
会对 a 进行隐式的类型转换,以String
为 hint 调用a
的[[toPrimitive]]
内部方法,实际就是调用a.toString
,然后再alert
,所以在模态对话框中显示a
函数的字符串表示。因为a被toString了
为什么大神们都要从函数的角度去分析呢?
运算符 运算符 他是用来计算 、 赋值、 等操作。
只不过
分组运算符 ()
特殊。 他可以提升变量优先级
任何一个运算符,单独使用都会报错
这是一个函数定义,但是不符合函数定义规范,所以保错
也是一个函数定义,此时(2)是一个分组运算,@rambo_panda 提到的,计算优先级提升,计算完毕后不影响原来函数的定义
其和一下等价
//也和这个等价