函数声明和函数表达式——函数声明和函数表达式的异同

| 阅读数:--次| 作者:js,javascript
摘要:上文结合自己的理解聊了聊函数声明的声明提前(提升),并解释了函数表达式为什么没有声明提前。该文我们再聊一聊函数声明和函数表达式的区别以及如何区分函数声明和函数表达式,当然该文内容和上文会有内容上的交叉。如果有对函数声明提前不太了解的小伙伴可以猛戳这里查看相关内容。

上一篇:《函数声明和函数表达式——函数声明的声明提前》

写在前面的前面

十三号一时兴起去看了《大圣归来》,看完后为啥我也有想当自来水的冲动了。。。至于详细的感受啥的也不便评论,但是这个赞绝对是要点的。

写在前面

上文结合自己的理解聊了聊函数声明的声明提前(提升),并解释了函数表达式为什么没有声明提前。Today我们再聊一聊函数声明和函数表达式的区别以及如何区分函数声明和函数表达式,当然该文内容和上文会有内容上的交叉。如果有对函数声明提前不太了解的小伙伴可以猛戳这里查看相关内容。

下面我们主要聊聊函数声明和函数表达式之间的异同。

相同点

注:函数声明和函数表达式的相同点包括但不限于以下几点

  1. 函数是一个值,所以和其他值一样,函数也可以进行被输出、被赋值、作为参数传给其他函数等相关操作,不管函数是以什么方式被定义的,当然和其他值的输出还是有些区别的。

    我们先来输出这个值:

    function nameAlert(name){
    	alert('博主的名字是:' + name + ' 。');
    }
    alert(nameAlert);

    注意输出的结果并不是1,而是这个函数的整个源代码,即输出结果为:

    function nameAlert(name){
    	alert('博主的名字是:' + name + ' 。');
    }
  2. 作为参数传给其他函数。

    例子双手呈上:

    function nameAlert(name){
    	alert('博主的名字是:' + name + ' 。');
    }
    var anotherNameAlert=nameAlert;
    anotherNameAlert('myvin');

    该例子中将函数nameAlert作为参数传给了anotherNameAlert,然后anotherNameAlert也指向了该函数。

    这里就涉及到了函数的传递,函数的传递是传引用,就是说函数存在内存中的某个位置,nameAlertanotherNameAlert是都是函数的一个引用,把函数名nameAlert赋值给anotherNameAlert的时候,它们引用的都是同一个函数。

    所以anotherNameAlert的输出结果为:

    博主的名字是:myvin 。

当然函数还有其他特点,在此不再介绍,感兴趣的可以自己总结下。

不同点

注:函数声明和函数表达式的不同点包括但不限于以下几点

相对函数声明和函数表达式之间的相同点,它们的不同点更应该值得我们关注。下面我结合自己的理解聊聊。

  1. 函数声明必须有标识符,也就是常说的函数名;函数表达式可以省略函数名。

    关于它们的定义的不同小伙伴们应该都知道,我们简单重复一遍。

    如下:

    函数声明(要带标识符)

    function functionName(arg1, arg2, ...){
    	<!-- function body -->
    }

    函数表达式

    • 省略标识符

      var  variable=function(arg1, arg2, ...){
      		<!-- function body -->
      }
    • 带有标识符

      var  variable=function functionName(arg1, arg2, ...){
      		<!-- function body -->
      }
  2. 函数声明会提前(上文主要讲的就是介个)。

    在此我引用我上文解释过的:

    函数声明是在预执行期执行的,就是说函数声明是在浏览器准备执行代码的时候执行的。因为函数声明在预执行期被执行,所以到了执行期,函数声明就不再执行(人家都执行过了自然就不再执行了)。

    例子的话还是前文的说真话函数:

    sayTruth();<!-- 函数声明 -->
    function sayTruth(){
    	alert('myvin is handsome.');
    }
    
    sayTruth();<!-- 函数表达式 -->
    var sayTruth=function(){
    	alert('myvin is handsome.');
    }

    即函数声明的话sayTruth()可以提前调用,就是不请自来的那种,而函数表达式是什么时候遇到什么时候执行。

    函数声明提前是它们很大的一个不同点,理解这一点对于我们函数的应用有很大帮助,能使我们避免一些错误。

  3. ECMAScript规范中表示,函数声明语句可以出现在全局代码中,或者内嵌在其他函数中,但是不能出现在循环、条件判、或者try/finally以及with语句中。

    对于这条,可能会有所疑问:“上文不是有一个函数声明出现在if循环中的么”。的确是这样,但是规定下发了,遵守不遵守就是另一回事了。JavaScript对于这条规范的实现并不是严格遵守的,FF中允许if中出现函数声明。

    但不管规范怎么样,造成这样的原因还是函数声明提前。

    还是引用上文的例子和说明:

    sayTruth(); 
    if(1){
    function sayTruth(){alert('myvin is handsome')};
    }
    else{
    function sayTruth(){alert('myvin is ugly')};
    }

    为什么呢?当然是声明提前了。因为函数声明提前,所以函数声明会在代码执行前进行解析,执行顺序是这样的,先解析function sayTruth(){alert('myvin is handsome')},在解析function sayTruth(){alert('myvin is ugly')},覆盖了前面的函数声明,当我们调用sayTruth()函数的时候,也就是到了代码执行期间,声明会被忽略,所以自然会输出myvin is ugly

  4. 可以创建一个函数表达式即刻执行。

    (function(){
    alert('博主的名字是:myvin 。');
    })()

    这样可以使得全局变量不受局部变量的影响,保持全局的干净。注意,括号里面的是表达式。

小了个结

没啥可结的,

Tomorrow is another day!!!

上一篇:《函数声明和函数表达式——函数声明的声明提前》

返回顶部
学到老代码浏览 关闭浏览