全面了解函数声明与函数表达式、变量提升


Posted in Javascript onAugust 09, 2016

函数的声明方式

在定义一个函数的时候通常有两种声明方式:

foo(){};   // 函数声明
var foo = function(){};  // 函数表达式

不同之处

1、函数表达式后面加括号可以直接执行
2、函数声明会提前预解析

预解析

让我们先看一个例子:

foo();     // 函数声明
foo_later();   // foo_later is not a function

function foo(){ console.log('函数声明'); }
var foo_later = function(){ console.log('函数表达式'); }

可以看到,函数声明foo被预解析了,它可以在其自身代码之前执行;而函数表达式foo_later则不能。要解决这个问题,我们先要弄清楚JavaScript解析器的工作机制。

变量提升(hoist)

JavaScript解析器会在自身作用域内将变量和函数声明提前(hoist),也就是说,上面的例子其实被解析器理解解析成了以下形式:

function foo(){ console.log('函数声明'); }  // 函数声明全部被提前
var foo_later;   // 函数表达式(变量声明)仅将变量提前,赋值操作没有被提前

foo();       
foo_later();   


foo_later = function(){ console.log('函数表达式'); }

这样也就可以解释,为什么在函数表达式之前调用函数,会返回错误了,因为它还没有被赋值,只是一个未定义变量,当然无法被执行。

同样的,我们也可以试着猜测下面这段代码的输出结果:

console.log(declaredLater);  

var declaredLater = "Now it's defined!";

console.log(declaredLater);

该段代码可以被解析成一下形式:

 

var declaredLater;     

console.log(declaredLater);  // undefined

declaredLater = "Now it's defined!";

console.log(declaredLater);  // Now it's defined!

 变量声明被提到最前(所以不会报出变量不存在的错误),但赋值没有被提前,所以第一次的输出结果是undefined。

需要注意的是

由于函数声明会被预解析,所以不要使用此种方法来声明不同函数。尝试猜想下面例子的输出结果:

if(true){
 function aaa(){
  alert('1');
 } 
}
else{
 function aaa(){
  alert('2');
 }
}

aaa();

与我们预想的不同,该段代码弹出的是“2”.这是因为两个函数声明在if语句被执行之前就被预解析了,所以if语句根本没有用,调用aaa()的时候直接执行了下面的函数。

总结

通过上面的讲解可以总结如下:

•变量的声明被提前到作用域顶部,赋值保留在原地

•函数声明整个“被提前”

•函数作为值赋给变量时只有变量“被提前”了,函数没有“被提前”

通过练习上面的实例自己多感受一下。另外,作为最佳实践:变量声明一定要放在作用域/函数的最上方(JavaScript 只有函数作用域!)。

以上这篇全面了解函数声明与函数表达式、变量提升就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
基于jquery异步传输json数据格式实例代码
Nov 23 Javascript
javascript中数组中求最大值示例代码
Dec 18 Javascript
js处理php输出时间戳对不上号的解决方法
Jun 20 Javascript
简介JavaScript中setUTCSeconds()方法的使用
Jun 12 Javascript
jquery实现网页的页面平滑滚动效果代码
Nov 02 Javascript
SublimeText自带格式化代码功能之reindent
Dec 27 Javascript
深入学习jQuery Validate表单验证(二)
Jan 18 Javascript
jQuery获取select选中的option的value值实现方法
Aug 29 Javascript
解决修复npm安装全局模块权限的问题
May 17 Javascript
Vue.js 中 axios 跨域访问错误问题及解决方法
Nov 21 Javascript
vue项目使用高德地图的定位及关键字搜索功能的实例代码(踩坑经验)
Mar 07 Javascript
vue+elementUI 实现内容区域高度自适应的示例
Sep 26 Javascript
jQuery 生成svg矢量二维码
Aug 09 #Javascript
浅谈JavaScript中变量和函数声明的提升
Aug 09 #Javascript
浅谈js基本数据类型和typeof
Aug 09 #Javascript
js中判断变量类型函数typeof的用法总结
Aug 09 #Javascript
详解js实现线段交点的三种算法
Aug 09 #Javascript
完美解决jQuery符号$与其他javascript 库、框架冲突的问题
Aug 09 #Javascript
jQuery对checkbox 复选框的全选全不选反选的操作
Aug 09 #Javascript
You might like
PHP 正则判断中文UTF-8或GBK的思路及具体实现
2013/11/26 PHP
PHP获取数组的键与值方法小结
2015/06/13 PHP
[原创]PHP获取数组表示的路径方法分析【数组转字符串】
2017/09/01 PHP
phpcms实现验证码替换及phpcms实现全站搜索功能教程详解
2017/12/13 PHP
PHP+ajax实现二级联动菜单功能示例
2018/08/10 PHP
js获取或设置当前窗口url参数的小例子
2013/10/14 Javascript
document.addEventListener使用介绍
2014/03/07 Javascript
js获取网页可见区域、正文以及屏幕分辨率的高度
2014/05/15 Javascript
css与javascript跨浏览器兼容性总结
2014/09/15 Javascript
JS动态修改iframe高度和宽度的方法
2015/04/01 Javascript
JavaScript实现页面5秒后自动跳转的方法
2015/04/16 Javascript
实例详解angularjs和ajax的结合使用
2015/10/22 Javascript
jQuery实现查找链接文字替换属性的方法
2016/06/27 Javascript
bootstrap多种样式进度条展示
2016/12/20 Javascript
JS定时检测任务任务完成后执行下一步的解决办法
2016/12/22 Javascript
javascript简单链式调用案例分析
2017/05/10 Javascript
js随机生成一个验证码
2017/06/01 Javascript
Angular2.0/4.0 使用Echarts图表的示例代码
2017/12/07 Javascript
vue中render函数的使用详解
2018/10/12 Javascript
JavaScript查看代码运行效率console.time()与console.timeEnd()用法
2019/01/18 Javascript
JavaScript 性能提升之路(推荐)
2019/04/10 Javascript
Nuxt.js实战和配置详解
2019/08/05 Javascript
阿望教你用vue写扫雷小游戏
2020/01/20 Javascript
[52:15]2014 DOTA2国际邀请赛中国区预选赛5.21 HGT VS LGD-GAMING
2014/05/23 DOTA
Python使用defaultdict读取文件各列的方法
2017/05/11 Python
python实现数据库跨服务器迁移
2018/04/12 Python
python爬取网易云音乐评论
2018/11/16 Python
使用Python做垃圾分类的原理及实例代码附源码
2019/07/02 Python
使用Python的networkx绘制精美网络图教程
2019/11/21 Python
Sephora丝芙兰印尼官方网站:购买化妆品和护肤品
2018/07/02 全球购物
乌克兰网上珠宝商店:GoldSoveren
2020/03/31 全球购物
什么是会话Bean
2015/05/14 面试题
python re模块和正则表达式
2021/03/24 Python
民主生活会汇报材料
2014/12/15 职场文书
演讲开场白和结束语
2015/05/29 职场文书
Java无向树分析 实现最小高度树
2022/04/09 Javascript