JavaScript中函数表达式和函数声明及函数声明与函数表达式的不同


Posted in Javascript onNovember 15, 2015

函数表达式和函数声明

在ECMAScript中,创建函数的最常用的两个方法是函数表达式和函数声明,两者期间的区别是有点晕,因为ECMA规范只明确了一点:函数声明必须带有标示符(Identifier)(就是大家常说的函数名称),而函数表达式则可以省略这个标示符:

函数声明:

function 函数名称 (参数:可选){ 函数体 }

函数表达式:

function 函数名称(可选)(参数:可选){ 函数体 }

所以,可以看出,如果不声明函数名称,它肯定是表达式,可如果声明了函数名称的话,如何判断是函数声明还是函数表达式呢?ECMAScript是通过上下文来区分的,如果function foo(){}是作为赋值表达式的一部分的话,那它就是一个函数表达式,如果function foo(){}被包含在一个函数体内,或者位于程序的最顶部的话,那它就是一个函数声明。

function foo(){} // 声明,因为它是程序的一部分
 var bar = function foo(){}; // 表达式,因为它是赋值表达式的一部分
 new function bar(){}; // 表达式,因为它是new表达式
 (function(){
  function bar(){} // 声明,因为它是函数体的一部分
 })();

还有一种函数表达式不太常见,就是被括号括住的(function foo(){}),他是表达式的原因是因为括号 ()是一个分组操作符,它的内部只能包含表达式,我们来看几个例子:

  function foo(){} // 函数声明
  (function foo(){}); // 函数表达式:包含在分组操作符内

命名函数表达式

提到命名函数表达式,理所当然,就是它得有名字,前面的例子var bar = function foo(){};就是一个有效的命名函数表达式,但有一点需要记住:这个名字只在新定义的函数作用域内有效,因为规范规定了标示符不能在外围的作用域内有效:

var f = function foo(){
  return typeof foo; // foo是在内部作用域内有效
 };
 // foo在外部用于是不可见的
 console.log(typeof foo); // "undefined"
 console.log(f()); // "function"
var f = function foo(){
return foo; // foo是在内部作用域内有效
};
// foo在外部用于是不可见的
console.log(typeof foo); // "undefined"
console.log( f()==f); // "function"
console.log(f.name);//foo

既然,这么要求,那命名函数表达式到底有啥用啊?为啥要取名?

正如我们开头所说:给它一个名字就是可以让调试过程更方便,因为在调试的时候,如果在调用栈中的每个项都有自己的名字来描述,那么调试过程就太爽了,感受不一样嘛。

ps:JS中函数声明与函数表达式的不同

Js中的函数声明是指下面的形式:

function functionName(){ 
}

这样的方式来声明一个函数,而函数表达式则是类似表达式那样来声明一个函数,如:

var functionName = function(){ 
}

可能很多朋友在看到这两一种写法时会产生疑惑,这两种写法差不多,在应用中貌似也都是可行的,那他们有什么差别呢?

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

Javascript 相关文章推荐
javascript instanceof 内部机制探析
Oct 15 Javascript
JS限制上传图片大小不使用控件在本地实现
Dec 19 Javascript
jquery高效反选具体实现
May 05 Javascript
JavaScript排序算法之希尔排序的2个实例
Apr 04 Javascript
再分享70+免费的jquery 图片滑块效果插件和教程
Dec 15 Javascript
jquery实现九宫格大转盘抽奖
Nov 13 Javascript
JavaScript实现二分查找实例代码
Feb 22 Javascript
AngularJS 防止页面闪烁的方法
Mar 09 Javascript
js利用for in循环获取 一个对象的所有属性以及值的实例
Mar 30 Javascript
jQuery实现拼图小游戏(实例讲解)
Jul 24 jQuery
使用jQuery实现购物车结算功能
Aug 15 jQuery
javascript实现打砖块小游戏(附完整源码)
Sep 18 Javascript
浅谈JavaScript中的对象及Promise对象的实现
Nov 15 #Javascript
javascript 中的 delete及delete运算符
Nov 15 #Javascript
详解JavaScript函数对象
Nov 15 #Javascript
javascript中window.open在原来的窗口中打开新的窗口(不同名)
Nov 15 #Javascript
深入浅析JavaScript中prototype和proto的关系
Nov 15 #Javascript
apply和call方法定义及apply和call方法的区别
Nov 15 #Javascript
JavaScript和HTML DOM的区别与联系及Javascript和DOM的关系
Nov 15 #Javascript
You might like
sae使用smarty模板的方法
2013/12/17 PHP
php使用mysqli向数据库添加数据的方法
2015/03/20 PHP
程序员的表白神器“520”大声喊出来
2016/05/20 PHP
PHP yield关键字功能与用法分析
2019/01/03 PHP
Laravel框架实现调用百度翻译API功能示例
2019/05/30 PHP
jQuery 核心函数以及jQuery对象
2010/03/23 Javascript
jQuery html()方法使用不了无法显示内容的问题
2014/08/06 Javascript
javascript中clone对象详解
2014/12/03 Javascript
js中实现字符串和数组的相互转化详解
2016/01/24 Javascript
jQuery实现右下角可缩放大小的层完整实例
2016/06/20 Javascript
关于JavaScript数组你所不知道的3件事
2016/08/24 Javascript
Node.js用readline模块实现输入输出
2016/12/16 Javascript
最常见和最有用的字符串相关的方法详解
2017/02/06 Javascript
DVA框架统一处理所有页面的loading状态
2017/08/25 Javascript
详解vue-admin和后端(flask)分离结合的例子
2018/02/12 Javascript
代码详解javascript模块加载器
2018/03/04 Javascript
Vue结合Video.js播放m3u8视频流的方法示例
2018/05/04 Javascript
webpack4打包vue前端多页面项目
2018/09/17 Javascript
vue与原生app的对接交互的方法(混合开发)
2018/11/28 Javascript
详解基于electron制作一个node压缩图片的桌面应用
2019/01/29 Javascript
vuex管理状态仓库使用详解
2020/07/29 Javascript
利用ctypes提高Python的执行速度
2016/09/09 Python
Win10下python 2.7.13 安装配置方法图文教程
2018/09/18 Python
Python使用修饰器进行异常日志记录操作示例
2019/03/19 Python
Python图片的横坐标汉字实例
2019/12/04 Python
Python接口自动化判断元素原理解析
2020/02/24 Python
html5 跨文档消息传输示例探讨
2013/04/01 HTML / CSS
Bose法国官网:购买耳机、扬声器、家庭影院、专业音响
2017/12/21 全球购物
经贸日语专业个人求职信
2013/12/13 职场文书
读书活动总结范文
2014/04/26 职场文书
个人反四风对照检查材料思想汇报
2014/09/23 职场文书
大学辅导员述职报告
2015/01/10 职场文书
疾病证明书
2015/06/19 职场文书
Golang生成Excel文档的方法步骤
2021/06/09 Golang
MySQL时区造成时差问题
2022/04/13 MySQL
VUE解决跨域问题Access to XMLHttpRequest at
2022/05/06 Vue.js