ホームページ  >  に質問  >  本文

javascript - 为什么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)}?

PHP中文网PHP中文网2750日前424

全員に返信(4)返信します

  • PHP中文网

    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 函数的字符串表示。

    返事
    0
  • 巴扎黑

    巴扎黑2017-04-10 15:38:25

    因为a被toString了

    返事
    0
  • 巴扎黑

    巴扎黑2017-04-10 15:38:25

    为什么大神们都要从函数的角度去分析呢?

    运算符 运算符 他是用来计算 、 赋值、 等操作。
    只不过 分组运算符 () 特殊。 他可以 提升变量优先级

    任何一个运算符,单独使用都会报错

    +;  //  Uncaught SyntaxError: Unexpected token }(…)   你让我加谁啊?
    *;  //  你他妈让我 谁乘谁 啊?
    
    // 同理
    ();  // 同理 你让我做什么??  我 
    
    var a = (1);
    var b = (undefined);
    var a1 = +1;
    var a2 = *1; // TODO 骚年 失望了吧?  * / 这些有一个专用名词我压根没记住(最他妈讨厌记这些概念) 意思就是 有些 运算符 是必须 >1个参数 你才能使用。 - +  单参运算符  * / 多参运算符  (请允许我私自这么叫吧)  
    
    

    返事
    0
  • PHP中文网

    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
    

    返事
    0
  • キャンセル返事