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


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 相关文章推荐
javascript中如何处理引号编码"
Aug 15 Javascript
轻松学习jQuery插件EasyUI EasyUI创建CRUD应用
Nov 30 Javascript
js仿百度音乐全选操作
Jan 13 Javascript
js实现显示手机号码效果
Mar 09 Javascript
前端主流框架vue学习笔记第一篇
Jul 26 Javascript
微信小程序实现的贪吃蛇游戏【附源码下载】
Jan 03 Javascript
select获取下拉框的值 下拉框默认选中方法
Feb 28 Javascript
JavaScript的级联函数用法简单示例【链式调用】
Mar 26 Javascript
Vue 组件修改根实例的数据的方法
Apr 02 Javascript
js中值引用和地址引用实例分析
Jun 21 Javascript
基于JavaScript获取url参数2种方法
Apr 17 Javascript
Javascript类型判断相关例题及解析
Aug 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
资料注册后发信小技巧
2006/10/09 PHP
ThinkPHP php 框架学习笔记
2009/10/30 PHP
php数据结构与算法(PHP描述) 查找与二分法查找
2012/06/21 PHP
PHP常用数组函数介绍
2014/07/28 PHP
php创建无限级树型菜单
2015/11/05 PHP
PHP中使用mpdf 导出PDF文件的实现方法
2018/10/22 PHP
php+mysql实现的无限分类方法类定义与使用示例
2020/05/27 PHP
一页面多XMLHttpRequest对象
2007/01/22 Javascript
js 编写规范
2010/03/03 Javascript
ExtJS[Desktop]实现图标换行示例代码
2013/11/17 Javascript
js call方法详细介绍(js 的继承)
2013/11/18 Javascript
jquery获取一个元素下面相同子元素的个数代码
2014/07/31 Javascript
简介JavaScript中strike()方法的使用
2015/06/08 Javascript
全面解析JavaScript的Backbone.js框架中的Router路由
2016/05/05 Javascript
Javascript基础学习笔记(菜鸟必看篇)
2016/07/22 Javascript
js实现一键复制功能
2017/03/16 Javascript
第一个Vue插件从封装到发布
2017/11/22 Javascript
详解微信图片防盗链“此图片来自微信公众平台 未经允许不得引用”的解决方案
2019/04/04 Javascript
微信小程序实现搜索指定景点周边美食、酒店
2019/05/18 Javascript
一起写一个即插即用的Vue Loading插件实现
2019/10/31 Javascript
JS中自定义事件的使用与触发操作实例分析
2019/11/01 Javascript
[05:09]第二届DOTA2亚洲邀请赛决赛日比赛集锦:iG 3:0 OG夺冠
2017/04/05 DOTA
python实现封装得到virustotal扫描结果
2014/10/05 Python
python实现简单socket通信的方法
2016/04/19 Python
python自动化脚本安装指定版本python环境详解
2017/09/14 Python
python类的方法属性与方法属性的动态绑定代码详解
2017/12/27 Python
使用pyplot.matshow()函数添加绘图标题
2020/06/16 Python
微软开源最强Python自动化神器Playwright(不用写一行代码)
2021/01/05 Python
专业实习自我鉴定
2013/10/29 职场文书
计算机网络专业自荐书
2014/06/09 职场文书
职业道德模范事迹材料
2014/08/24 职场文书
无财产无子女离婚协议书范文
2014/09/14 职场文书
英语通知范文
2015/04/22 职场文书
幼儿园园长工作总结2015
2015/05/25 职场文书
Python机器学习之基于Pytorch实现猫狗分类
2021/06/08 Python
Python docx库删除复制paragraph及行高设置图片插入示例
2022/07/23 Python