JS中函数声明与函数表达式的异同

相同点

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

  1. 函数是一个值,所以和其他值一样,函数也可以进行被输出、被赋值、作为参数传给其他函数等相关操作,不管函数是以什么方式被定义的,当然和其他值的输出还是有些区别的。 我们先来输出这个值:
function nameAlert(name){
    alert('博主的名字是:' + name + ' 。');
}
alert(nameAlert);
注意输出的结果并不是1,而是这个函数的整个源代码,即输出结果为:

function nameAlert(name){
    alert('博主的名字是:' + name + ' 。');
}
  1. 作为参数传给其他函数。 该例子中将函数nameAlert作为参数传给了anotherNameAlert,然后anotherNameAlert也指向了该函数。 这里就涉及到了函数的传递,函数的传递是传引用,就是说函数存在内存中的某个位置,nameAlertanotherNameAlert是都是函数的一个引用,把函数名nameAlert赋值给anotherNameAlert的时候,它们引用的都是同一个函数。 所以anotherNameAlert的输出结果为: 博主的名字是:myvin 。
function nameAlert(name){
    alert('博主的名字是:' + name + ' 。');
}
var anotherNameAlert=nameAlert;
anotherNameAlert('myvin');

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

不同点

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

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

  1. 函数声明必须有标识符,也就是常说的函数名;函数表达式可以省略函数名。 关于它们的定义的不同小伙伴们应该都知道,我们简单重复一遍。 如下: 函数声明(要带标识符) 函数表达式
    • 省略标识符
    var  variable=function(arg1, arg2, ...){
            <!-- function body -->
    }
    • 带有标识符
    var  variable=function functionName(arg1, arg2, ...){
            <!-- function body -->
    }
function functionName(arg1, arg2, ...){
    <!-- function body -->
}
  1. 函数声明会提前 函数声明是在预执行期执行的,就是说函数声明是在浏览器准备执行代码的时候执行的。因为函数声明在预执行期被执行,所以到了执行期,函数声明就不再执行(人家都执行过了自然就不再执行了)。 例子的话还是前文的说真话函数: 即函数声明的话sayTruth()可以提前调用,就是不请自来的那种,而函数表达式是什么时候遇到什么时候执行。 函数声明提前是它们很大的一个不同点,理解这一点对于我们函数的应用有很大帮助,能使我们避免一些错误。
sayTruth();<!-- 函数声明 -->
function sayTruth(){
    alert('myvin is handsome.');
}

sayTruth();<!-- 函数表达式 -->
var sayTruth=function(){
    alert('myvin is handsome.');
}
  1. ECMAScript规范中表示,函数声明语句可以出现在全局代码中,或者内嵌在其他函数中,但是不能出现在循环、条件判、或者try/finally以及with语句中。 对于这条,可能会有所疑问:“上文不是有一个函数声明出现在if循环中的么”。的确是这样,但是规定下发了,遵守不遵守就是另一回事了。JavaScript对于这条规范的实现并不是严格遵守的,FF中允许if中出现函数声明。 但不管规范怎么样,造成这样的原因还是函数声明提前。 还是引用上文的例子和说明: 为什么呢?当然是声明提前了。因为函数声明提前,所以函数声明会在代码执行前进行解析,执行顺序是这样的,先解析function sayTruth(){alert('myvin is handsome')},在解析function sayTruth(){alert('myvin is ugly')},覆盖了前面的函数声明,当我们调用sayTruth()函数的时候,也就是到了代码执行期间,声明会被忽略,所以自然会输出myvin is ugly
sayTruth(); 
if(1){
function sayTruth(){alert('myvin is handsome')};
}
else{
function sayTruth(){alert('myvin is ugly')};
}
 
  1. 可以创建一个函数表达式即刻执行。 这样可以使得全局变量不受局部变量的影响,保持全局的干净。注意,括号里面的是表达式。
(function(){
alert('博主的名字是:myvin 。');
})()

事实上,js的解析器对函数声明与函数表达式并不是一视同仁地对待的。对于函数声明,js解析器会优先读取,确保在所有代码执行之前声明已经被解析,而函数表达式,如同定义其它基本类型的变量一样,只在执行到某一句时也会对其进行解析,所以在实际中,它们还是会有差异的,具体表现在,当使用函数声明的形式来定义函数时,可将调用语句写在函数声明之前,而后者,这样做的话会报错。

参考链接:http://www.cnblogs.com/myvin/p/4649789.html

http://blog.csdn.net/one_and_only4711/article/details/6361131

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏老九学堂

稳准狠!最全讲解!初学者必看的C语言字符串知识

字符数组和普通数组一样,也是通过下标引用各个元素。 【示例】输出字符数组中的元素。

921
来自专栏猿人谷

《C++ primer》--第1,2章小结

 1、变量初始化:  定义变量时,应该给变量赋初始值,除非确定将变量用于其他意图之前会覆盖这个初值。如果不能保证读取变量之前重置变量,就应该初始化变量。变量...

22010
来自专栏Vamei实验室

Python基础02 基本数据类型

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢! 简单的数据类型以及赋值 变量不需要声明 P...

1955
来自专栏大数据钻研

Java基础语法

java 基 础 语 法 一个Java程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念...

2916
来自专栏大闲人柴毛毛

稳扎稳打JavaScript(一)——作用域链内存模型

几个概念 在开始之前,先了解几个概念。 1.1. 作用域 作用域是指当前正在执行的代码能够访问到变量的范围; 每个函数都有各自的作用域,存储函数所有的局部变量...

4778
来自专栏web前端-

函数基础知识回顾

  String    Number   Boolean   Null    undefined    //占有固定的内存大小,如数值型占八个字节,布尔类型...

753
来自专栏黑泽君的专栏

java中,方法参数是基本类型和引用类型的区别

当参数是基本类型时,在调用方法时将值传递到方法中,运行方法,运行结束方法退出,对原本main中定义的变量没有任何操作(方法中没有return)。即:此时只跟栈有...

1752
来自专栏HappenLee的技术杂谈

C++雾中风景6:拷贝构造函数与赋值函数

这里我们显式声明了拷贝构造函数与赋值构造函数,接下来我们用一小段代码测试一下上面定义的类。(其他函数的定义并不完整,读者可以之行补全)

912
来自专栏Bingo的深度学习杂货店

Python3 编程注意点

整除 3//2 数字转字符串 str(number),字符串转数字 int(str) 字符串所有方法不修改字符串本身 .title() .upper() .l...

3545
来自专栏Golang语言社区

go interface

Go不是一种典型的OO语言,它在语法上不支持类和继承的概念。 没有继承是否就无法拥有多态行为了呢?答案是否定的,Go语言引入了一种新类型—Interface,它...

3435

扫码关注云+社区

领取腾讯云代金券