最通俗易懂的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 相关文章推荐
在JavaScript并非所有的一切都是对象
Apr 11 Javascript
jquery获取对象的方法足以应付常见的各种类型的对象
May 14 Javascript
javascript实现playfair和hill密码算法
Dec 07 Javascript
JavaScript事件委托技术实例分析
Feb 06 Javascript
JavaScript数组对象赋值用法实例
Aug 04 Javascript
Bootstrap图片轮播组件使用实例解析
Jun 30 Javascript
15位和18位身份证JS校验的简单实例
Jul 18 Javascript
JSON 必知必会 观后记
Oct 27 Javascript
jquery请求servlet实现ajax异步请求的示例
Jun 03 jQuery
深入解析koa之异步回调处理
Jun 17 Javascript
解决layui轮播图有数据不显示的情况
Sep 16 Javascript
Vuejs通过拖动改变元素宽度实现自适应
Sep 02 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
php 上传文件类型判断函数(避免上传漏洞 )
2010/06/08 PHP
Laravel 4 初级教程之安装及入门
2014/10/30 PHP
php使用fgetcsv读取csv文件出现乱码的解决方法
2014/11/08 PHP
基于jQuery的弹出框插件
2012/03/18 Javascript
Juery解决tablesorter中文排序和字符范围的方法
2015/05/06 Javascript
JavaScript实现带缓冲效果的随屏滚动漂浮广告代码
2015/11/06 Javascript
jQuery简单实现仿京东分类导航层效果
2016/06/07 Javascript
AngularJS中比较两个数组是否相同
2016/08/24 Javascript
基于Javascript倒计时效果
2016/12/22 Javascript
AngularJs中 ng-repeat指令中实现含有自定义指令的动态html的方法
2017/01/19 Javascript
jQuery插件FusionWidgets实现的AngularGauge图效果示例【附demo源码】
2017/03/23 jQuery
Three.js入门之hello world以及如何绘制线
2017/09/25 Javascript
vue router自动判断左右翻页转场动画效果
2017/10/10 Javascript
jQuery中$原理实例分析
2018/08/13 jQuery
基于AngularJs select绑定数字类型的问题
2018/10/08 Javascript
微信小程序如何修改本地缓存key中单个数据的详解
2019/04/26 Javascript
使用vue完成微信公众号网页小记(推荐)
2019/04/28 Javascript
vue项目前端错误收集之sentry教程详解
2019/05/27 Javascript
NProgress显示顶部进度条效果及使用详解
2019/09/21 Javascript
Vue清除定时器setInterval优化方案分享
2020/07/21 Javascript
Vue 同步异步存值取值实现案例
2020/08/05 Javascript
Python实现的一个简单LRU cache
2014/09/26 Python
使用Pyrex来扩展和加速Python程序的教程
2015/04/13 Python
Python自动化开发学习之三级菜单制作
2017/07/14 Python
Python在不同目录下导入模块的实现方法
2017/10/27 Python
python绘制中国大陆人口热力图
2018/11/07 Python
在python中利用最小二乘拟合二次抛物线函数的方法
2018/12/29 Python
使用CodeMirror实现Python3在线编辑器的示例代码
2019/01/14 Python
python 基于Apscheduler实现定时任务
2020/12/15 Python
HTML5上传文件显示进度的实现代码
2012/08/30 HTML / CSS
HTML5中form如何关闭自动完成功能的方法
2018/07/02 HTML / CSS
英国拖鞋购买网站:Bedroom Athletics
2020/02/28 全球购物
幼儿园教师工作感言
2014/02/15 职场文书
pytorch Dropout过拟合的操作
2021/05/27 Python
Redis如何实现分布式锁
2021/08/23 Redis
MySQL的意向共享锁、意向排它锁和死锁
2022/07/15 MySQL