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


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学习笔记(四) Number 数字类型
Jun 19 Javascript
JavaScript实现弹出子窗口并传值给父窗口
Dec 18 Javascript
javascript委托(Delegate)blur和focus用法实例分析
May 26 Javascript
js文本框输入内容智能提示效果
Dec 02 Javascript
jQuery css() 方法动态修改CSS属性
Sep 25 Javascript
原生JS实现匀速图片轮播动画
Oct 18 Javascript
jQuery select自动选中功能实现方法分析
Nov 28 Javascript
JQ中$(window).load和$(document).ready区别与执行顺序
Mar 01 Javascript
详解VueJS应用中管理用户权限
Feb 02 Javascript
Angularjs实现页面模板清除的方法
Jul 20 Javascript
vue.js input框之间赋值方法
Aug 24 Javascript
vue 中的动态传参和query传参操作
Nov 09 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中MD5函数使用实例代码
2008/06/07 PHP
sae使用smarty模板的方法
2013/12/17 PHP
php中的filesystem文件系统函数介绍及使用示例
2014/02/13 PHP
迁移PHP版本到PHP7
2015/02/06 PHP
php实现图片局部打马赛克的方法
2015/02/11 PHP
Laravel 中获取上一篇和下一篇数据
2015/07/27 PHP
php实现图片上传并进行替换操作
2016/03/15 PHP
php实现将HTML页面转换成word并且保存的方法
2016/10/14 PHP
PHP常用函数总结(180多个)
2016/12/25 PHP
PHP实现mysqli批量执行多条语句的方法示例
2017/07/22 PHP
PHP实现将上传图片自动缩放到指定分辨率,并保持清晰度封装类示例
2019/06/17 PHP
JavaScript中跨域调用Flash的方法
2014/08/11 Javascript
Javascript中Array.prototype.map()详解
2014/10/22 Javascript
基于javascript实现九宫格大转盘效果
2020/05/28 Javascript
Bootstrap优化站点资源、响应式图片、传送带使用详解3
2016/10/14 Javascript
JavaScript的事件机制详解
2017/01/17 Javascript
js Canvas绘制圆形时钟教程
2017/02/06 Javascript
js中json对象和字符串的理解及相互转化操作实现方法
2017/09/22 Javascript
为react组件库添加typescript类型提示的方法
2020/06/15 Javascript
iview实现图片上传功能
2020/06/29 Javascript
JavaScript实现点击图片换背景
2020/11/20 Javascript
基于JavaScript实现轮播图效果
2021/01/02 Javascript
python 测试实现方法
2008/12/24 Python
酷! 程序员用Python带你玩转冲顶大会
2018/01/17 Python
python计算两个地址之间的距离方法
2018/06/09 Python
Python 使用list和tuple+条件判断详解
2019/07/30 Python
详解基于python-django框架的支付宝支付案例
2019/09/23 Python
Python实现把多维数组展开成DataFrame
2019/11/30 Python
如何为DataGridView添加一个定制的Column Type
2014/01/21 面试题
国贸专业大学生职业生涯规划范文
2014/01/10 职场文书
金融行业职业生涯规划范文
2014/01/17 职场文书
致跳高运动员加油稿
2014/02/12 职场文书
个人安全承诺书
2014/05/22 职场文书
简易版租房协议书范本
2014/10/13 职场文书
2015年英语教研组工作总结
2015/05/23 职场文书
vue实现水波涟漪效果的点击反馈指令
2021/05/31 Vue.js