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


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 相关文章推荐
csdn 论坛技术区平均给分功能
Nov 07 Javascript
window.requestAnimationFrame是什么意思,怎么用
Jan 13 Javascript
js(jQuery)获取时间的方法及常用时间类搜集
Oct 23 Javascript
javascript圆盘抽奖程序实现原理和完整代码例子
Jun 03 Javascript
基于BootStrap Metronic开发框架经验小结【九】实现Web页面内容的打印预览和保存操作
May 12 Javascript
第二篇Bootstrap起步
Jun 21 Javascript
Bootstrap风格的WPF样式
Dec 07 Javascript
详解A标签中href=""的几种用法
Aug 20 Javascript
javascript函数的节流[throttle]与防抖[debounce]
Nov 15 Javascript
js设计模式之单例模式原理与用法详解
Aug 15 Javascript
浅谈Vue.set实际上是什么
Oct 17 Javascript
vue监听dom大小改变案例
Jul 29 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入门学习知识点三 PHP上传
2011/07/14 PHP
PHP源码之explode使用说明
2011/08/05 PHP
PHP批量采集下载美女图片的实现代码
2013/06/03 PHP
PHP二分查找算法示例【递归与非递归方法】
2016/09/29 PHP
获取服务器传来的数据 用JS去空格的正则表达式
2012/03/26 Javascript
JS字符串截取函数实例
2013/12/27 Javascript
利用浏览器全屏api实现js全屏
2014/01/16 Javascript
JS实现往下不断流动网页背景的方法
2015/02/27 Javascript
jQuery基于ajax实现星星评论代码
2015/08/07 Javascript
基于jquery实现图片上传本地预览功能
2016/01/08 Javascript
学习JavaScript事件流和事件处理程序
2016/01/25 Javascript
JavaScript的词法结构精华篇
2018/10/17 Javascript
elementUI Tree 树形控件的官方使用文档
2019/04/25 Javascript
node.js express框架简介与实现
2019/07/23 Javascript
Vue 3.0双向绑定原理的实现方法
2019/10/23 Javascript
通过实例解析chrome如何在mac环境中安装vue-devtools插件
2020/07/10 Javascript
详解vue中v-model和v-bind绑定数据的异同
2020/08/10 Javascript
python实现的守护进程(Daemon)用法实例
2015/06/02 Python
详解Python网络爬虫功能的基本写法
2016/01/28 Python
Python批量合并有合并单元格的Excel文件详解
2018/04/05 Python
浅谈Python中的全局锁(GIL)问题
2019/01/11 Python
对dataframe数据之间求补集的实例详解
2019/01/30 Python
Python小程序 控制鼠标循环点击代码实例
2019/10/08 Python
Pandas 解决dataframe的一列进行向下顺移问题
2019/12/27 Python
pytorch 彩色图像转灰度图像实例
2020/01/13 Python
tensorflow mnist 数据加载实现并画图效果
2020/02/05 Python
python判断两个序列的成员是否一样的实例代码
2020/03/01 Python
Keras预训练的ImageNet模型实现分类操作
2020/07/07 Python
纯CSS3制作漂亮带动画效果的主机价格表
2015/04/25 HTML / CSS
使用CSS3创建动态菜单效果
2015/07/10 HTML / CSS
巴西购物网站:Submarino
2020/01/19 全球购物
外贸采购员岗位职责
2014/03/08 职场文书
学习2014年全国两会心得体会
2014/03/12 职场文书
仓库管理员岗位职责
2014/03/19 职场文书
2014年财务科工作总结
2014/11/11 职场文书
先进事迹材料怎么写
2014/12/30 职场文书