最通俗易懂的javascript变量提升详解


Posted in Javascript onAugust 05, 2017

如下所示:

a = 'ghostwu';
var a;
console.log( a );

在我没有讲什么是变量提升,以及变量提升的规则之前, 或者你没有学习过变量提升,如果按照现有的javascript理解, 对于上述的例子,你可能会认为第3行代码的输出结果应该是undefined, 因为第二行是var a; 声明变量,但是没有赋值,所以a的值是undefined, 但是正确的结果是ghostwu. 至于为什么,请继续往下看!

console.log( a );
var a = 'ghostwu';

对于上面这个例子,第一行代码,你可能认为报错, 因为在输出a之前,没有定义a变量, 但是正确的结果是undefined. 嗯,好像有点莫名奇妙,javascript太bug了.

要搞清楚为什么,首先我们要明确以下2点:

javascript代码并不是一行一行往下执行的.

javascript执行分为2个步骤:

编译(词法解释/预解释)

执行

其次,当我们碰到 var a = "ghostwu" 定义一个变量的时候, 其实js把这句话看成是2个阶段的事, var a 发生在编译阶段, a = 'ghostwu'发生在执行阶段. 然后 var a会被提升到当前作用域的最前面, a = 'ghostwu'留在原地等待执行阶段,所以:

a = 'ghostwu';
var a;
console.log( a );

//上面这段代码经过编译之后,变成下面这样

var a; //被提升到当前作用域的最前面
a = 'ghostwu'; //留在原地,等待执行
console.log( a );
console.log( a ); 
var a = 'ghostwu';

//上面这段代码,经过编译之后,变成下面这样

var a;
console.log( a );
a = 'ghostwu';

看完编译后的代码,你明白了吗?

在接着讲下面之前,我们先明确函数常见的2种定义方式:

//函数声明, 形如:
  function show(){
   console.log( '函数声明方式' );
  }

  //函数表达式, 形如:
  var show = function(){
   console.log( '表达式方式' );
  }

因为表达式和函数声明,在编译阶段,会产生不同的解释效果。

show();
  function show(){
   console.log( a );
   var a = 'ghostwu';
  }

对于上面这段代码,会在编译阶段,如何解释呢?记住下面这句话就行了:

函数声明会被提升

所以,上面的代码,经过编译之后,就变成了下面这样:

function show(){ //函数声明被提升到 当前作用域的最前面
   var a; //var声明被提升到当前作用域的最前面, 注意,他不会提升到函数的外面, 因为当前的作用域是在函数中
   console.log( a );
   a = 'ghostwu';
  }
  show();

所以,上面的结果就是undefined;

对于函数表达式,是不会提升的, 看下面的例子:

show(); //报错,show is not a function
var show = function(){
 console.log( 'ghostwu' );
}
//对于上面这段表达式代码,经过编译之后:
var show;
show(); //执行之后就是 undefined(), 所以在表达式定义之前,调用函数报错了
show = function(){
 console.log( 'ghostwu' ); 
}
show(); //你好
  var show;
  function show(){
   console.log( '你好' );
  }
  show = function(){
   console.log( 'hello' );
  }

上面这段代码,结果为什么会是 '你好'?

因为: 当出现同名的函数声明,变量声明的时候, 函数声明会被优先提升,变量声明会被忽略。 所以经过编译之后,就变成:

function show(){
   console.log( '你好' );
  }
  show(); //你好
  show = function(){
   console.log( 'hello' );
  }
  show();//如果这里在调用一次,就是hello, 因为show函数体在执行阶段 被 重新赋值了

如果有同名的函数声明,后面的会覆盖前面的,如下:

show(); //how are you
  var show;
  function show(){
   console.log( 'hello' );
  } 
  show = function(){
   console.log( '你好' );
  }
  function show(){
   console.log( 'how are you!' );
  }
//上面的代码经过编译之后,变成如下形式:
  function show(){
   console.log( 'how are you!' );
  }
  show(); //how are you
  show = function(){
   console.log( '你好' );
  }
  show(); //如果在这里再执行一次,结果:你好
//思考题: 请问下面的结果是什么? 为什么? 写下你的答案
   show();
   var a = true;
   if( a ){
    function show(){
     console.log( 1 );
    }
   }else {
    function show(){
     console.log( 2 );
   }
   }

以上这篇最通俗易懂的javascript变量提升详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
检测是否已安装 .NET Framework 3.5的js脚本
Feb 14 Javascript
如何将JS的变量值传递给ASP变量
Dec 10 Javascript
js实现倒计时时钟的示例代码
Dec 17 Javascript
JQuery教学之性能优化
May 14 Javascript
JQuery实现可直接编辑的表格
Apr 16 Javascript
js实现select跳转菜单新窗口效果代码分享(超简单)
Aug 21 Javascript
在Ubuntu系统上安装Node.JS的教程
Oct 15 Javascript
javascript正则表达式定义(语法)总结
Jan 08 Javascript
漫谈JS引擎的运行机制 你应该知道什么
Jun 15 Javascript
JavaScript省市区三级联动菜单效果
Sep 21 Javascript
AngularJS使用ng-app自动加载bootstrap框架问题分析
Jan 04 Javascript
示例vue 的keep-alive缓存功能的实现
Dec 13 Javascript
Vue2.0 vue-source jsonp 跨域请求
Aug 04 #Javascript
js分页之前端代码实现和请求处理
Aug 04 #Javascript
微信小程序 rich-text的使用方法
Aug 04 #Javascript
Easyui和zTree两种方式分别实现树形下拉框
Aug 04 #Javascript
JS中使用media实现响应式布局
Aug 04 #Javascript
React Native第三方平台分享的实例(Android,IOS双平台)
Aug 04 #Javascript
node中Express 动态设置端口的方法
Aug 04 #Javascript
You might like
深入for,while,foreach遍历时间比较的详解
2013/06/08 PHP
php加速器eAccelerator的配置参数、API详解
2014/05/05 PHP
PHP整合七牛实现上传文件
2015/07/03 PHP
php 问卷调查结果统计
2015/10/08 PHP
PHP5.4起内置web服务器使用方法
2016/08/09 PHP
PHP实现的redis主从数据库状态检测功能示例
2017/07/20 PHP
用js实现的页面关键字密度查询代码
2007/12/27 Javascript
web基于浏览器的本地存储方法应用
2012/11/27 Javascript
jquery 实现上下滚动效果示例代码
2013/08/09 Javascript
将HTML格式的String转化为HTMLElement的实现方法
2014/08/07 Javascript
javascript检测是否联网的实现代码
2014/09/28 Javascript
Angular的$http与$location
2016/12/26 Javascript
微信小程序五子棋游戏AI实现方法【附demo源码下载】
2019/02/20 Javascript
JavaScript实现点击图片换背景
2020/11/20 Javascript
[45:38]DOTA2上海特级锦标赛主赛事日 - 1 胜者组第一轮#1Liquid VS Alliance第一局
2016/03/02 DOTA
python多进程操作实例
2014/11/21 Python
python绘制双柱形图代码实例
2017/12/14 Python
python实现mysql的读写分离及负载均衡
2018/02/04 Python
django2+uwsgi+nginx上线部署到服务器Ubuntu16.04
2018/06/26 Python
对Python中的条件判断、循环以及循环的终止方法详解
2019/02/08 Python
python实现扫描ip地址的小程序
2019/04/16 Python
详解在Python中以绝对路径或者相对路径导入文件的方法
2019/08/30 Python
最新2019Pycharm安装教程 亲测
2020/02/28 Python
django 利用Q对象与F对象进行查询的实现
2020/05/15 Python
在主流系统之上安装Pygame的方法
2020/05/20 Python
图解Python中深浅copy(通俗易懂)
2020/09/03 Python
python获取本周、上周、本月、上月及本季的时间代码实例
2020/09/08 Python
python实现视频压缩功能
2020/12/18 Python
使用HTML5的Notification API制作web通知的教程
2015/05/08 HTML / CSS
澳大利亚最早和最古老的巨型游戏专家:Yardgames
2020/02/20 全球购物
服装设计专业毕业生推荐信
2013/11/09 职场文书
学校大课间活动方案
2014/01/30 职场文书
2014年党委工作总结
2014/11/22 职场文书
导游词300字
2015/02/13 职场文书
golang goroutine顺序输出方式
2021/04/29 Golang
基于Python实现一个春节倒计时脚本
2022/01/22 Python