资讯专栏INFORMATION COLUMN

JavaScript—— 函数声明和函数表达式有什么不同吗?

FleyX / 1921人阅读

摘要:函数声明和函数表达式的区别函数声明只能出现在程序或函数体内。所以,在等语义为语句的代码块中存在函数声明,由于函数提升特性,会破坏掉原本的语义。

这篇谈一下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等语义为语句的代码块中存在函数声明,由于函数提升特性,会破坏掉原本的语义。函数提升后,作用域也会为为该函数的下的函数作用域,这样原本属于函数"内部"的函数就变为外部的了。

这里接两个大神的文章:

函数声明和函数表达式——函数声明的声明提前 - myvin - 博客园

详解Javascript 函数声明和函数表达式的区别 - JackWang-CUMT - 博客园

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/83029.html

相关文章

  • 你知道JavaScript中的结果值是什么

    摘要:你知道中的每条语句甚至表达式都有一个结果值吗当你在浏览器中测试代码时,经常会在控制台的输出结果的最后面多出一条,大部分为,这个就是一个结果值。特例变量声明语句函数声明语句的结果值为。 你知道JavaScript中的每条语句、甚至表达式都有一个结果值吗? 当你在浏览器中测试代码时,经常会在控制台的输出结果的最后面多出一条,大部分为undefined,这个undefined就是一个结果值。...

    YanceyOfficial 评论0 收藏0
  • 由 ECMA 规范解读 Javascript 可执行上下文概念

    摘要:不包括作为其嵌套函数的被解析的源代码。作用域链当代码在一个环境中执行时,会创建变量对象的一个作用域链。栈结构最顶层的执行环境称为当前运行的执行环境,最底层是全局执行环境。无限制函数上下文。或者抛出异常退出一个执行环境。 前言 其实规范这东西不是给人看的,它更多的是给语言实现者提供参考。但是当碰到问题找不到答案时,规范往往能提供想要的答案 。偶尔读一下能够带来很大的启发和思考,如果只读一...

    daryl 评论0 收藏0
  • 体验javascript之美-第五课 匿名函数自执行闭包是一回事儿

    摘要:大家想想怎么做什么是匿名函数自执行并如何在实际库中应用匿名函数自执行,注意,注意,只有这个名字和没有其它名字,比如封闭空间,这个是为了让大家好理解自己造的词语。 通过本节课你将学到: 1.什么是函数表达式和函数声明 2.first-class function 3.引用和复制的区别 4.函数传参是怎么回事儿 5.关于函数的this和arguments 6.什么是匿名函数自执行并如何在...

    _Suqin 评论0 收藏0
  • 翻译连载 |《你不知道的JS》姊妹篇 |《JavaScript 轻量级函数式编程》- 第 2 章:函

    摘要:从某些方面来讲,这章回顾的函数知识并不是针对函数式编程者,非函数式编程者同样需要了解。什么是函数针对函数式编程,很自然而然的我会想到从函数开始。如果你计划使用函数式编程,你应该尽可能多地使用函数,而不是程序。指的是一个函数声明的形参数量。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson - 《You-Dont-Know-JS》作者 关于译者:...

    Riddler 评论0 收藏0
  • 函数知多少(一)

    摘要:从定义函数说起如何定义函数一般来说,定义函数的方式有两种,分别是函数声明和函数表达式。我们声明了一个变量,接着又定义了一个函数,我们通过监视窗口发现一直被定义成了一个函数,显然,函数声明的优先级高于变量声明。 从定义函数说起 如何定义函数? 一般来说,定义函数的方式有两种,分别是函数声明和函数表达式。 //函数声明 function foo1() { console.log(h...

    2json 评论0 收藏0

发表评论

0条评论

阅读需要支付1元查看
<