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


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 相关文章推荐
高效的获取当前元素是父元素的第几个子元素
Oct 15 Javascript
JavaScript使用DeviceOne开发实战(三)仿微信应用
Dec 02 Javascript
jQuery弹簧插件编写基础之“又见弹窗”
Dec 11 Javascript
利用Javascript仿Excel的数据透视分析功能
Sep 07 Javascript
JS+DIV实现的卷帘效果示例
Mar 22 Javascript
基于VUE移动音乐WEBAPP跨域请求失败的解决方法
Jan 16 Javascript
layui实现给某一列加点击事件
Oct 26 Javascript
微信小程序实现吸顶特效
Jan 08 Javascript
vue集成openlayers加载geojson并实现点击弹窗教程
Sep 24 Javascript
微信小程序基于ColorUI构建皮皮虾短视频去水印组件
Nov 04 Javascript
Vue3 响应式侦听与计算的实现
Nov 11 Javascript
js实现菜单跳转效果
Dec 11 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下正则来匹配dede模板标签的代码
2010/08/21 PHP
php学习之 循环结构实现代码
2011/06/09 PHP
Yii清理缓存的方法
2016/01/06 PHP
PHP观察者模式定义与用法实例分析
2019/03/22 PHP
JavaScript判断访问的来源是手机还是电脑,用的哪种浏览器
2013/12/12 Javascript
JS+CSS实现的经典tab选项卡效果代码
2015/09/16 Javascript
js检测iframe是否加载完成的方法
2015/11/26 Javascript
Node之简单的前后端交互(实例讲解)
2017/11/14 Javascript
Vue.js 点击按钮显示/隐藏内容的实例代码
2018/02/08 Javascript
详解npm 配置项registry修改为淘宝镜像
2018/09/07 Javascript
vue.js父子组件通信动态绑定的实例
2018/09/28 Javascript
手挽手带你学React之React-router4.x的使用
2019/02/14 Javascript
20个必会的JavaScript面试题(小结)
2019/07/02 Javascript
详解nvm管理多版本node踩坑
2019/07/26 Javascript
vue 框架下自定义滚动条(easyscroll)实现方法
2019/08/29 Javascript
JS原型和原型链原理与用法实例详解
2020/02/05 Javascript
Openlayers实现地图全屏显示
2020/09/28 Javascript
Python自定义scrapy中间模块避免重复采集的方法
2015/04/07 Python
python中文件变化监控示例(watchdog)
2017/10/16 Python
Python数据分析之双色球统计单个红和蓝球哪个比例高的方法
2018/02/03 Python
python try 异常处理(史上最全)
2019/03/07 Python
python中selenium库的基本使用详解
2020/07/31 Python
HTML5进阶段内联标签汇总(小篇)
2016/07/13 HTML / CSS
HTML5 层的叠加的实现
2020/07/07 HTML / CSS
洲际酒店集团美国官网:IHG美国
2017/11/16 全球购物
英国最大最好的无人机商店:Drones Direct
2019/07/12 全球购物
ECCO英国官网:丹麦鞋履品牌
2019/09/03 全球购物
迪卡侬波兰体育用品商店:Decathlon波兰
2020/03/31 全球购物
企业治理工作自我评价
2013/09/26 职场文书
小学开学典礼主持词
2014/03/19 职场文书
教师先进个人材料
2014/12/17 职场文书
升学宴学生致辞
2015/09/29 职场文书
Django使用channels + websocket打造在线聊天室
2021/05/20 Python
vue实现可以快进后退的跑马灯组件
2022/04/08 Vue.js
python缺失值填充方法示例代码
2022/12/24 Python