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


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 相关文章推荐
一些常用的JS功能函数代码
Jun 23 Javascript
js中取得变量绝对值的方法
Jan 03 Javascript
javascript数据类型示例分享
Jan 19 Javascript
javascript实现输出指定行数正方形图案的方法
Aug 03 Javascript
浅谈$('div a') 与$('div>a')的区别
Jul 18 Javascript
谈谈jQuery之Deferred源码剖析
Dec 19 Javascript
一个例子轻松学会Vue.js
Jan 02 Javascript
微信小程序开发之Tabbar实例详解
Jan 09 Javascript
详解axios在vue中的简单配置与使用
May 10 Javascript
js中对象和面向对象与Json介绍
Jan 21 Javascript
bootstrap-table formatter 使用vue组件的方法
May 09 Javascript
微信小程序一周时间表功能实现
Oct 17 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 开源框架22个简单简介
2009/08/24 PHP
用php简单实现加减乘除计算器
2014/01/06 PHP
[原创]PHP global全局变量经典应用与注意事项分析【附$GLOBALS用法对比】
2019/07/12 PHP
5款Javascript颜色选择器
2009/10/25 Javascript
收集的10个免费的jQuery相册
2011/02/26 Javascript
JS中Iframe之间传值的方法
2013/03/11 Javascript
解析js中获得父窗口链接getParent方法以及各种打开窗口的方法
2013/06/19 Javascript
node.js不得不说的12点内容
2014/07/14 Javascript
JQuery实现表格动态增加行并对新行添加事件
2014/07/30 Javascript
angular-cli修改端口号【angular2】
2017/04/19 Javascript
js下载文件并修改文件名
2017/05/08 Javascript
webpack多页面开发实践
2017/12/18 Javascript
nodejs操作mongodb的填删改查模块的制作及引入实例
2018/01/02 NodeJs
jQuery NProgress.js加载进度插件的简单使用方法
2018/01/31 jQuery
vue实现简单的星级评分组件源码
2018/11/16 Javascript
Openlayers实现地图全屏显示
2020/09/28 Javascript
[47:26]完美世界DOTA2联赛 LBZS vs Forest 第二场 11.07
2020/11/09 DOTA
Python中subprocess模块用法实例详解
2015/05/20 Python
python 实现上传图片并预览的3种方法(推荐)
2017/07/14 Python
Python快速排序算法实例分析
2017/11/29 Python
Python实现按特定格式对文件进行读写的方法示例
2017/11/30 Python
Python函数返回不定数量的值方法
2019/01/22 Python
Python语法分析之字符串格式化
2019/06/13 Python
详解用Python为直方图绘制拟合曲线的两种方法
2019/08/21 Python
Django 自定义分页器的实现代码
2019/11/24 Python
利用python实现.dcm格式图像转为.jpg格式
2020/01/13 Python
在Django中预防CSRF攻击的操作
2020/03/13 Python
从Pytorch模型pth文件中读取参数成numpy矩阵的操作
2021/03/04 Python
让IE支持HTML5的方法
2012/12/11 HTML / CSS
阿迪达斯丹麦官网:adidas丹麦
2016/10/01 全球购物
花园仓库建筑:Garden Buildings Direct
2018/02/16 全球购物
JENNIFER BEHR官网:各种耳环和发饰
2020/06/07 全球购物
优秀英语专业毕业生求职信
2013/11/23 职场文书
会计学生自我鉴定
2014/02/06 职场文书
汉语言文学专业求职信
2014/06/19 职场文书
2015年班长个人工作总结
2015/04/03 职场文书