最通俗易懂的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 相关文章推荐
彪哥1.1(智能表格)提供下载
Sep 07 Javascript
利用jquery.qrcode在页面上生成二维码且支持中文
Feb 12 Javascript
基于jQuery全屏焦点图左右切换插件responsiveslides
Sep 07 Javascript
基于jQuery实现Ajax验证用户名是否存在实例
Mar 30 Javascript
jQuery插件AjaxFileUpload实现ajax文件上传
May 05 Javascript
jQuery利用sort对DOM元素进行排序操作
Nov 07 Javascript
Vue计算属性的学习笔记
Mar 22 Javascript
vue 多入口文件搭建 vue多页面搭建的实例讲解
Mar 12 Javascript
vue实现点击当前标签高亮效果【推荐】
Jun 22 Javascript
一些手写JavaScript常用的函数汇总
Apr 16 Javascript
js实现打字小游戏
Dec 17 Javascript
基于vue的video播放器的实现示例
Feb 19 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 set_time_limit(0)长连接的实现分析
2010/03/02 PHP
基于python发送邮件的乱码问题的解决办法
2013/04/25 PHP
php实现按文件名搜索文件的远程文件查找器
2014/05/10 PHP
php 模拟 asp.net webFrom 按钮提交事件实例
2014/10/13 PHP
ThinkPHP实现二级循环读取的方法
2014/11/03 PHP
php经典算法集锦
2015/11/14 PHP
Symfony控制层深入详解
2016/03/17 PHP
php分享朋友圈的实现代码
2019/02/18 PHP
tp5.1 框架路由操作-URL生成实例分析
2020/05/26 PHP
关于JavaScript中原型继承中的一点思考
2012/07/25 Javascript
jQuery简单图表peity.js使用示例
2014/05/02 Javascript
JavaScript导出Excel实例详解
2014/11/25 Javascript
深入探寻javascript定时器
2015/01/02 Javascript
jQuery实现仿腾讯微博滑出效果报告每日天气的方法
2015/05/11 Javascript
jQuery dataTables与jQuery UI 对话框dialog的使用教程
2016/09/02 Javascript
微信小程序 wxapp画布 canvas详细介绍
2016/10/31 Javascript
深入理解与使用keep-alive(配合router-view缓存整个路由页面)
2018/09/25 Javascript
vue element ui validate 主动触发错误提示操作
2020/09/21 Javascript
Python群发邮件实例代码
2014/01/03 Python
Python数据结构之Array用法实例
2014/10/09 Python
Python中字符编码简介、方法及使用建议
2015/01/08 Python
Python中统计函数运行耗时的方法
2015/05/05 Python
Tensorflow的可视化工具Tensorboard的初步使用详解
2018/02/11 Python
Python列表解析配合if else的方法
2018/06/23 Python
python入门:这篇文章带你直接学会python
2018/09/14 Python
使用Python向DataFrame中指定位置添加一列或多列的方法
2019/01/29 Python
将string类型的数据类型转换为spark rdd时报错的解决方法
2019/02/18 Python
Mac 使用python3的matplot画图不显示的解决
2019/11/23 Python
Python使用urllib模块对URL网址中的中文编码与解码实例详解
2020/02/18 Python
Html5 postMessage实现跨域消息传递
2016/03/11 HTML / CSS
Sony C++笔试题
2013/03/10 面试题
护士个人简历自荐信
2013/10/18 职场文书
如何撰写一封出色的求职信
2014/04/27 职场文书
道德大讲堂实施方案
2014/05/14 职场文书
小学生关于梦想的演讲稿
2014/08/22 职场文书
员工升职自荐信
2015/03/27 职场文书