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


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 相关文章推荐
newxtree.js代码
Mar 13 Javascript
js禁止小键盘输入数字功能代码
Aug 01 Javascript
图片Slider 带左右按钮的js示例
Aug 30 Javascript
node.js中的fs.symlink方法使用说明
Dec 15 Javascript
javascript实现点击单选按钮链接转向对应网址的方法
Aug 12 Javascript
jquery实现表格中点击相应行变色功能效果【实例代码】
May 09 Javascript
BootStrap智能表单实战系列(四)表单布局介绍
Jun 13 Javascript
JS获取日期的方法实例【昨天,今天,明天,前n天,后n天的日期】
Sep 28 Javascript
Vue组件之单向数据流的解决方法
Nov 10 Javascript
vue 解决移动端弹出键盘导致页面fixed布局错乱的问题
Nov 06 Javascript
vue+animation实现翻页动画
Jun 29 Javascript
Openlayers显示地理位置坐标的方法
Sep 28 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新手上路(八)
2006/10/09 PHP
浅谈PHP 闭包特性在实际应用中的问题
2009/10/30 PHP
PHP利用hash冲突漏洞进行DDoS攻击的方法分析
2015/03/26 PHP
列举PHP的Yii 2框架的开发优势
2015/07/03 PHP
WordPress中获取页面链接和标题的相关PHP函数用法解析
2015/12/17 PHP
PHP获取日期对应星期、一周日期、星期开始与结束日期的方法
2018/06/22 PHP
PHP使用mongoclient简单操作mongodb数据库示例
2019/02/08 PHP
JavaScript 操作键盘的Enter事件(键盘任何事件),兼容多浏览器
2010/10/11 Javascript
jQuery实现简单的tab标签页效果
2016/09/12 Javascript
JavaScript利用正则表达式替换字符串中的内容
2016/12/12 Javascript
Ionic+AngularJS实现登录和注册带验证功能
2017/02/09 Javascript
vue安装和使用scss及sass与scss的区别详解
2018/10/15 Javascript
jQuery实现动态生成年月日级联下拉列表示例
2019/05/11 jQuery
vue基于better-scroll仿京东分类列表
2020/06/30 Javascript
javascript实现扫雷简易版
2020/08/18 Javascript
使用jQuery实现购物车
2020/10/29 jQuery
[41:08]2014 DOTA2国际邀请赛中国区预选赛 HGT VS NE
2014/05/22 DOTA
Python读取Json字典写入Excel表格的方法
2018/01/03 Python
python DataFrame 取差集实例
2019/01/30 Python
使用pygame编写Flappy bird小游戏
2020/03/14 Python
详解CSS3的box-shadow属性制作边框阴影效果的方法
2016/05/10 HTML / CSS
HTML5 在canvas中绘制矩形附效果图
2014/06/23 HTML / CSS
瑞典时尚服装购物网站:Miinto.se
2017/10/30 全球购物
新加坡领先的在线生活方式和杂货购物网站:EAMART
2019/04/02 全球购物
一套PHP的笔试题
2013/05/31 面试题
医学生职业规划范文
2014/01/05 职场文书
长辈证婚人证婚词
2014/01/09 职场文书
幼儿园庆六一游园活动方案
2014/01/29 职场文书
承认错误的检讨书
2014/01/30 职场文书
入党自我评价范文
2014/02/02 职场文书
售后服务经理岗位职责范本
2014/02/22 职场文书
讲党性心得体会
2014/09/03 职场文书
优秀班集体事迹材料
2014/12/25 职场文书
会计岗位职责
2015/02/03 职场文书
初任公务员培训心得体会
2016/01/08 职场文书
大学生入党自我鉴定范文
2019/06/21 职场文书