最通俗易懂的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编写的放大镜插件
Mar 23 Javascript
老生常谈 js中this的指向
Jun 30 Javascript
JavaScript常用代码书写规范的超全面总结
Sep 11 Javascript
Angular页面间切换及传值的4种方法
Nov 04 Javascript
JS异步文件分片断点上传的实现思路
Dec 25 Javascript
Vue 2.0的数据依赖实现原理代码简析
Jul 10 Javascript
vue项目开发中setTimeout等定时器的管理问题
Sep 13 Javascript
详解Vue 如何监听Array的变化
Jun 06 Javascript
vue自动化路由的实现代码
Sep 30 Javascript
微信小程序 点击切换样式scroll-view实现代码实例
Oct 11 Javascript
JavaScript canvas基于数组生成柱状图代码实例
Mar 06 Javascript
vue+iview实现分页及查询功能
Nov 17 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
php表单敏感字符过滤类
2014/12/08 PHP
PHP判断是否为空的几个函数对比
2015/04/21 PHP
PHP模拟QQ登录的方法
2015/07/29 PHP
php时间戳转换代码详解
2019/08/04 PHP
TP5框架请求响应参数实例分析
2019/10/17 PHP
javascript学习笔记(四)function函数部分
2014/09/30 Javascript
Javascript 中创建自定义对象的方法汇总
2014/12/04 Javascript
javascript实现动态标签云
2015/10/16 Javascript
JavaScript隐式类型转换
2016/03/15 Javascript
JS中frameset框架弹出层实例代码
2016/04/01 Javascript
浅谈JavaScript中的this指针和引用知识
2016/08/05 Javascript
jQuery实现简单的tab标签页效果
2016/09/12 Javascript
微信小程序 出现错误:{"baseresponse":{"errcode":-80002,"errmsg":""}}解决办法
2017/02/23 Javascript
微信小程序-滚动消息通知的实例代码
2017/08/03 Javascript
vue+webpack 打包文件 404 页面空白的解决方法
2018/02/28 Javascript
vuejs2.0运用原生js实现简单拖拽元素功能
2020/08/21 Javascript
vue+express+jwt持久化登录的方法
2019/06/14 Javascript
[02:58]献给西雅图的情书_高清
2014/05/29 DOTA
[13:39]2014 DOTA2华西杯精英邀请赛 5 25 NewBee VS DK第一场
2014/05/26 DOTA
下载给定网页上图片的方法
2014/02/18 Python
用Python编写web API的教程
2015/04/30 Python
Python 搭建Web站点之Web服务器网关接口
2016/11/06 Python
利用python微信库itchat实现微信自动回复功能
2017/05/18 Python
Python 模拟登陆的两种实现方法
2017/08/10 Python
python实现对csv文件的列的内容读取
2018/07/04 Python
python/sympy求解矩阵方程的方法
2018/11/08 Python
Python判断一个文件夹内哪些文件是图片的实例
2018/12/07 Python
自定义Django默认的sitemap站点地图样式
2020/03/04 Python
python 获取字典特定值对应的键的实现
2020/09/29 Python
Converse匡威法国官网:美国著名帆布鞋品牌
2018/12/05 全球购物
建议书怎么写
2014/03/12 职场文书
减负增效提质方案
2014/05/23 职场文书
教师群众路线教育实践活动学习笔记
2014/11/05 职场文书
团拜会主持词
2015/07/04 职场文书
2015年暑期社会实践方案
2015/07/14 职场文书
Python 如何利用ffmpeg 处理视频素材
2021/11/27 Python