最通俗易懂的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 相关文章推荐
Google Suggest ;-) 基于js的动态下拉菜单
Oct 11 Javascript
用js代码和插件实现wordpress雪花飘落效果的四种方法
Dec 15 Javascript
使用纯javascript实现放大镜效果
Mar 18 Javascript
总结JavaScript三种数据存储方式之间的区别
May 03 Javascript
用js实现放大镜的效果的简单实例
May 23 Javascript
webstorm添加*.vue文件支持
May 08 Javascript
微信小程序实现卡片左右滑动效果的示例代码
May 01 Javascript
vue如何自动化打包测试环境和正式环境的dist/test文件
Jun 06 Javascript
使用imba.io框架得到比 vue 快50倍的性能基准
Jun 17 Javascript
vue中使用v-for时为什么不能用index作为key
Apr 04 Javascript
vue自定义组件实现双向绑定
Jan 13 Vue.js
手动实现vue2.0的双向数据绑定原理详解
Feb 06 Vue.js
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
德生PL330的评价与改造
2021/03/02 无线电
简单实现PHP留言板功能
2016/12/21 PHP
摘自百度的图片轮换效果代码
2007/11/19 Javascript
javascript操作referer详细解析
2014/03/10 Javascript
jquery插件开发之实现md5插件
2014/03/17 Javascript
jQuery获取标签文本内容和html内容的方法
2015/03/27 Javascript
半个小时学json(json传递示例)
2016/12/25 Javascript
浅谈gulp创建完整的项目流程
2017/12/20 Javascript
Vue实现带进度条的文件拖动上传功能
2018/02/23 Javascript
JS获取并处理php数组的方法实例分析
2018/09/04 Javascript
使用RN Animated做一个“添加购物车”动画的方法
2018/09/12 Javascript
如何利用javascript接收json信息并进行处理
2020/08/06 Javascript
浅谈vue websocket nodeJS 进行实时通信踩到的坑
2020/09/22 NodeJs
JavaScript实现随机点名小程序
2020/10/29 Javascript
vue点击Dashboard不同内容 跳转到同一表格的实例
2020/11/13 Javascript
解决vue页面刷新,数据丢失的问题
2020/11/24 Vue.js
深入理解Python中字典的键的使用
2015/08/19 Python
基于python3 类的属性、方法、封装、继承实例讲解
2017/09/19 Python
简单实现python进度条脚本
2017/12/18 Python
Python使用Pickle库实现读写序列操作示例
2018/06/15 Python
python实现Flappy Bird源码
2018/12/24 Python
tensorflow通过模型文件,使用tensorboard查看其模型图Graph方式
2020/01/23 Python
Django使用Profile扩展User模块方式
2020/05/14 Python
微信html5页面调用第三方位置导航的示例
2018/03/14 HTML / CSS
美国花布包包品牌:Vera Bradley
2017/08/11 全球购物
四川internet信息高速公路(C#)笔试题
2012/02/29 面试题
实习教师自我鉴定
2013/12/09 职场文书
建筑工地门卫岗位职责
2014/04/30 职场文书
2014法制宣传日活动总结
2014/07/09 职场文书
政风行风建设整改方案
2014/10/27 职场文书
2014年乡镇党建工作总结
2014/11/11 职场文书
同意报考公务员证明
2015/06/17 职场文书
Python 数据结构之十大经典排序算法一文通关
2021/10/16 Python
php去除deprecated的实例方法
2021/11/17 PHP
Win10鼠标轨迹怎么开 Win10显示鼠标轨迹方法
2022/04/06 数码科技
Windows server 2022创建创建林、域树、子域的步骤
2022/06/25 Servers