最通俗易懂的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 相关文章推荐
jQuery+CSS实现菜单滑动伸展收缩(仿淘宝)
Mar 22 Javascript
IE8对JS通过属性和数组遍历解析不一样的地方探讨
May 06 Javascript
FireBug 调试JS入门教程 如何调试JS
Dec 23 Javascript
javascript使用call调用微信API
Dec 15 Javascript
浅谈javascript中的instanceof和typeof
Feb 27 Javascript
javascript汉字拼音互转的简单实例
Oct 09 Javascript
轻松玩转BootstrapTable(后端使用SpringMVC+Hibernate)
Sep 06 Javascript
Cocos2d实现刮刮卡效果
Dec 20 Javascript
对layer弹出框中icon数字参数的说明介绍
Sep 04 Javascript
JS实现普通轮播图特效
Jan 01 Javascript
Vue路由管理器Vue-router的使用方法详解
Feb 05 Javascript
vue实现页面切换滑动效果
Jun 29 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
ThinkPHP使用心得分享-ThinkPHP + Ajax 实现2级联动下拉菜单
2014/05/15 PHP
Yii框架参数化查询中IN查询只能查询一个的解决方法
2017/05/20 PHP
JS正则中的RegExp对象对象
2012/11/07 Javascript
如何防止回车(enter)键提交表单
2014/05/11 Javascript
用html5 js实现点击一个按钮达到浏览器全屏效果
2014/05/28 Javascript
jQuery之Deferred对象详解
2014/09/04 Javascript
js用拖动滑块来控制图片大小的方法
2015/02/27 Javascript
javascript结合Canvas 实现简易的圆形时钟
2015/03/11 Javascript
jQuery获取当前点击的对象元素(实现代码)
2016/05/19 Javascript
jquery插件autocomplete用法示例
2016/07/01 Javascript
浅谈JS函数定义方式的区别
2016/10/30 Javascript
JS中解决谷歌浏览器记住密码输入框颜色改变功能
2017/02/13 Javascript
JavaScript实现简单的文本逐字打印效果示例
2018/04/12 Javascript
vue使用中的内存泄漏【推荐】
2018/07/10 Javascript
angularjs $http调用接口的方式详解
2018/08/13 Javascript
小程序云开发实战小结
2018/10/25 Javascript
layui弹出框Tab选项卡的示例代码
2019/09/04 Javascript
[43:26]完美世界DOTA2联赛PWL S2 Forest vs Rebirth 第二场 11.20
2020/11/23 DOTA
python列表的常用操作方法小结
2016/05/21 Python
Python表示矩阵的方法分析
2017/05/26 Python
用python写个自动SSH登录远程服务器的小工具(实例)
2017/06/17 Python
python numpy格式化打印的实例
2018/05/14 Python
如何为Python终端提供持久性历史记录
2019/09/03 Python
python3 实现口罩抽签的功能
2020/03/11 Python
Python垃圾回收机制三种实现方法
2020/04/27 Python
django rest framework serializers序列化实例
2020/05/13 Python
Python日志处理模块logging用法解析
2020/05/19 Python
Python操作Excel的学习笔记
2021/02/18 Python
戴森台湾线上商城:Dyson Taiwan
2018/05/21 全球购物
上海中网科技笔试题
2012/02/19 面试题
Linux管理员面试经常问道的相关命令
2013/04/29 面试题
sort命令的作用和用法
2013/08/25 面试题
新锐科技Java程序员面试题
2016/07/25 面试题
八项规定整改方案
2014/02/21 职场文书
企业家王石演讲稿:坚持与放下
2014/04/27 职场文书
办公室禁烟通知
2015/04/23 职场文书