Maison > Questions et réponses > le corps du texte
当在函数声明之后直接加括号,如下
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)}?
PHP中文网2017-04-10 15:38:25
这是个有意思的问题,尝试分析下。
在 ECMAScript 中,函数声明 (Function declaration, FD)与 具名函数表达式(Named function expresson, NFE)具有相同的语法:
FunctionDeclaration :
function Identifier ( FormalParameterListopt ) { FunctionBody }
FunctionExpression :
function Identifieropt ( FormalParameterListopt ) { FunctionBody }
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)
被解析为两条语句:
function a(b) {alert(b)} // FD
(1) // 表达式语句
console 显示的 1
是 (1)
求值的结果。(你可以把 function a(b){alert(b)}(1)
复制到JavaScript AST visualizer 查看生成的抽象语法树)
alert(a)
会对 a 进行隐式的类型转换,以 String
为 hint 调用 a
的 [[toPrimitive]]
内部方法,实际就是调用 a.toString
,然后再 alert
,所以在模态对话框中显示 a
函数的字符串表示。
巴扎黑2017-04-10 15:38:25
为什么大神们都要从函数的角度去分析呢?
运算符 运算符 他是用来计算 、 赋值、 等操作。
只不过 分组运算符 ()
特殊。 他可以 提升变量优先级
任何一个运算符,单独使用都会报错
+; // Uncaught SyntaxError: Unexpected token }(…) 你让我加谁啊?
*; // 你他妈让我 谁乘谁 啊?
// 同理
(); // 同理 你让我做什么?? 我
var a = (1);
var b = (undefined);
var a1 = +1;
var a2 = *1; // TODO 骚年 失望了吧? * / 这些有一个专用名词我压根没记住(最他妈讨厌记这些概念) 意思就是 有些 运算符 是必须 >1个参数 你才能使用。 - + 单参运算符 * / 多参运算符 (请允许我私自这么叫吧)
PHP中文网2017-04-10 15:38:25
这是一个函数定义,但是不符合函数定义规范,所以保错
function a(){
console.log(1);
}();
也是一个函数定义,此时(2)是一个分组运算,@rambo_panda 提到的,计算优先级提升,计算完毕后不影响原来函数的定义
function a(){
console.log(1);
}(2);
其和一下等价
function a(){
console.log(1);
}
(2);
//也和这个等价
function a(){console.log(1);}(2);
!function a(){console.log(1);}() // 函数被执行,返回结果true
(function a(){console.log(1);})() // 函数被执行,返回结果undefined
(function a(){console.log(1);}()) // 函数被执行,返回结果undefined