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


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 CSS样式控制 学习笔记
Jul 23 Javascript
jquery实现手机号码选号的方法
Jul 31 Javascript
JavaScript实现图片自动加载的瀑布流效果
Apr 11 Javascript
jQuery插件uploadify实现ajax效果的图片上传
Jun 18 Javascript
微信小程序 WXML、WXSS 和JS介绍及详解
Oct 08 Javascript
使用JavaScript获取URL中的参数(两种方法)
Nov 16 Javascript
bootstrap vue.js实现tab效果
Feb 07 Javascript
Angularjs+bootstrap+table多选(全选)支持单击行选中实现编辑、删除功能
Mar 27 Javascript
微信小程序商品详情页规格属性选择示例代码
Oct 30 Javascript
Node.js 中使用 async 函数的方法
Nov 20 Javascript
基于vue.js无缝滚动效果
Jan 25 Javascript
vue中watch和computed为什么能监听到数据的改变以及不同之处
Dec 27 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
自制短波长线天线频率预选器 - 成功消除B2K之流的镜像
2021/03/02 无线电
在IIS7.0下面配置PHP 5.3.2运行环境的方法
2010/04/13 PHP
使用PHP获取汉字的拼音(全部与首字母)
2013/06/27 PHP
PHP中把stdClass Object转array的几个方法
2014/05/08 PHP
js身份证验证超强脚本
2008/10/26 Javascript
基于jquery跨浏览器显示的file上传控件
2011/10/24 Javascript
基于jQuery中对数组进行操作的方法
2013/04/16 Javascript
Js参数值中含有单引号或双引号问题的解决方法
2013/11/06 Javascript
js实现黑色简易的滑动门网页tab选项卡效果
2015/08/31 Javascript
jQuery四种选择器使用及示例
2016/06/05 Javascript
js窗口震动小程序分享
2016/11/28 Javascript
jQuery动态增减行的实例代码解析(推荐)
2016/12/05 Javascript
jQuery实现圣诞节礼物传送(花式轮播)
2016/12/25 Javascript
AngularJS实现页面定时刷新
2017/03/14 Javascript
在Vant的基础上实现添加表单验证框架的方法示例
2018/12/05 Javascript
vue进入页面时滚动条始终在底部代码实例
2019/03/26 Javascript
Node.js一行代码实现静态文件服务器的方法步骤
2019/05/07 Javascript
深入浅出vue图片路径的实现
2019/09/04 Javascript
微信公众号开发之微信支付代码记录的实现
2019/10/16 Javascript
vue开发简单上传图片功能
2020/06/30 Javascript
Js Snowflake(雪花算法)生成随机ID的实现方法
2020/08/26 Javascript
vue实现禁止浏览器记住密码功能的示例代码
2021/02/03 Vue.js
python利用有道翻译实现"语言翻译器"的功能实例
2017/11/14 Python
更新修改后的Python模块方法
2019/03/03 Python
pyqt5 键盘监听按下enter 就登陆的实例
2019/06/25 Python
python excel和yaml文件的读取封装
2021/01/12 Python
Python使用paramiko连接远程服务器执行Shell命令的实现
2021/03/04 Python
德国孕妇装和婴童服装网上商店:bellybutton
2018/04/12 全球购物
高职教师岗位职责
2013/12/24 职场文书
不打扫卫生检讨书
2014/02/12 职场文书
建筑横幅标语
2014/10/09 职场文书
计划生育工作汇报
2014/10/28 职场文书
2015年司法局工作总结
2015/05/22 职场文书
导游词之贵州百里杜鹃
2019/10/29 职场文书
解析高可用Redis服务架构分析与搭建方案
2021/06/20 Redis
Python集合的基础操作
2021/11/01 Python