这篇谈一下JS函数声明与函数表达式的区别及要注意的地方:

函数声明主要有两种类型:

  • 函数声明

        function fn() {};
  • 函数表达式

        var fn = function () {};

这两种函数创建方式有区别吗?当然有,回想一下变量声明提升,这里函数也遵循这个规则。

JS函数声明和函数表达式的区别

FunctionDeclaration(函数声明)只能出现在Program(程序)或FunctionBody(函数体)内。从句法上讲,它们 不能出现在Block(块)({ ... })中,例如不能出现在 if、whilefor 语句中。因为 Block(块) 中只能包含Statement(语句), 而不能包含FunctionDeclaration(函数声明)这样的SourceElement(源元素)。

  另一方面,仔细看一看产生规则也会发现,唯一可能让Expression(表达式)出现在Block(块)中情形,就是让它作为ExpressionStatement(表达式语句)的一部分。但是,规范明确规定了ExpressionStatement(表达式语句)不能以关键字function开头。而这实际上就是说,FunctionExpression(函数表达式)同样也不能出现在Statement(语句)或Block(块)中(别忘了Block(块)就是由Statement(语句)构成的)。
由于存在上述限制,只要函数出现在块中(像上面例子中那样),实际上就应该将其看作一个语法错误,而不是什么函数声明或表达式。
那么我们应该在什么时候使用函数声明或函数表达式呢?函数声明只能出现在“程序代码”中,意味着只能在其它函数体中或者全局空间;它们的定义不能不能赋值给一个变量或属性,或者作为一个参数传递出现在函数调用中;

概括一下就是:绝对不要将会函数声明放在一条语句内。

  • Javascript 中函数声明和函数表达式是存在区别的,函数声明在JS解析时进行函数提升,因此在同一个作用域内,不管函数声明在哪里定义,该函数都可以进行调用。

  • 函数表达式的值是在JS运行时确定,并且在表达式赋值完成后,该函数才能调用。这个微小的区别,可能会导致JS代码出现意想不到的bug,让你陷入莫名的陷阱中。

        fn();                // "fn"
        function f n() {
            console.log("fn")
        };
        
        fn2();                // "Uncaught TypeError: undefined is not a function"
        var fn2 = function () {    
            alert("fn2");
        };

这段代码就是对上面文字的解释。所以,在if、while等语义为语句的代码块中存在函数声明,由于函数提升特性,会破坏掉原本的语义。函数提升后,作用域也会为为该函数的下的函数作用域,这样原本属于函数"内部"的函数就变为外部的了。

这里接两个大神的文章:


Queen
139 声望20 粉丝