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


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插件jquery倒计时插件分享
Dec 27 Javascript
JS使用replace()方法和正则表达式进行字符串的搜索与替换实例
Apr 10 Javascript
javascript 判断整数方法分享
Dec 16 Javascript
jquery中EasyUI使用技巧小结
Feb 10 Javascript
使用JQuery实现智能表单验证功能
Mar 08 Javascript
Avalonjs 实现简单购物车功能(实例代码)
Feb 07 Javascript
JS中利用swiper实现3d翻转幻灯片实例代码
Aug 25 Javascript
JS基于对象的特性实现去除数组中重复项功能详解
Nov 17 Javascript
使用 Node.js 开发资讯爬虫流程
Jan 07 Javascript
完美解决iview 的select下拉框选项错位的问题
Mar 02 Javascript
angular6 利用 ngContentOutlet 实现组件位置交换(重排)
Nov 02 Javascript
JS使用百度地图API自动获取地址和经纬度操作示例
Apr 16 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 GeoIP的使用教程
2011/03/09 PHP
微信红包随机生成算法php版
2016/07/21 PHP
js chrome浏览器判断代码
2010/03/28 Javascript
jQuery+.net实现浏览更多内容(改编php版本)
2013/03/28 Javascript
导航跟随滚动条置顶移动示例代码
2013/09/11 Javascript
jQuery表格插件datatables用法总结
2014/09/05 Javascript
了不起的node.js读书笔记之mongodb数据库交互
2014/12/22 Javascript
JavaScript对数字的判断与处理实例分析
2015/02/02 Javascript
JQuery判断checkbox是否选中及其它复选框操作方法合集
2015/06/01 Javascript
JAVASCRIPT代码编写俄罗斯方块网页版
2015/11/26 Javascript
客户端验证用户名和密码的方法详解
2016/06/16 Javascript
jquery html5 视频播放控制代码
2016/11/06 Javascript
JS经典正则表达式笔试题汇总
2016/12/15 Javascript
移动端界面的适配
2017/01/11 Javascript
Vue中保存用户登录状态实例代码
2017/06/07 Javascript
ES6扩展运算符用法实例分析
2017/10/31 Javascript
使用JavaScript生成罗马字符的实例代码
2018/06/08 Javascript
详解vue2.0+axios+mock+axios-mock+adapter实现登陆
2018/07/19 Javascript
JavaScript 浏览器对象模型BOM原理与常见用法实例分析
2019/12/16 Javascript
Python实现生成简单的Makefile文件代码示例
2015/03/10 Python
讲解Python中运算符使用时的优先级
2015/05/14 Python
Python实例一个类背后发生了什么
2016/02/09 Python
python装饰器简介---这一篇也许就够了(推荐)
2019/04/01 Python
在VS2017中用C#调用python脚本的实现
2019/07/31 Python
Python创建一个元素都为0的列表实例
2019/11/28 Python
6行Python代码实现进度条效果(Progress、tqdm、alive-progress​​​​​​​和PySimpleGUI库)
2020/01/06 Python
python实现Oracle查询分组的方法示例
2020/04/30 Python
python实现图片,视频人脸识别(opencv版)
2020/11/18 Python
地图可视化神器kepler.gl python接口的使用方法
2020/12/22 Python
python自动化发送邮件实例讲解
2021/01/04 Python
python脚本使用阿里云slb对恶意攻击进行封堵的实现
2021/02/04 Python
css3实现多个元素依次显示效果
2017/12/12 HTML / CSS
2014年党员个人工作总结
2014/12/02 职场文书
被告代理词范文
2015/05/25 职场文书
使用@Value值注入及配置文件组件扫描
2021/07/09 Java/Android
python可视化之颜色映射详解
2021/09/15 Python