最通俗易懂的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中常用的SET和GET
Jan 13 Javascript
用原生JavaScript实现jQuery的$.getJSON的解决方法
May 03 Javascript
javascript操作html控件实例(javascript添加html)
Dec 02 Javascript
javascript刷新父页面的各种方法汇总
Sep 03 Javascript
js实现网页多级级联菜单代码
Aug 20 Javascript
Node.js刷新session过期时间的实现方法推荐
May 18 Javascript
JS代码实现table数据分页效果
May 26 Javascript
深入浅析JS Function()构造函数
Aug 22 Javascript
HTML5+Canvas调用手机拍照功能实现图片上传(上)
Apr 21 Javascript
Node.js实现文件上传的示例
Jun 28 Javascript
百度地图去掉marker覆盖物或者去掉maker的label文字方法
Jan 26 Javascript
15个顶级开源JavaScript框架和库
Oct 10 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获取程序执行的时间
2013/06/09 PHP
php提取字符串中网站url地址的方法
2014/12/03 PHP
php源码的安装方法和实例
2019/09/26 PHP
js静态作用域的功能。
2006/12/25 Javascript
js捕获鼠标右键菜单中的粘帖事件实现代码
2013/04/01 Javascript
js 使FORM表单的所有元素不可编辑的示例代码
2013/10/17 Javascript
javascript中实现兼容JAVA的hashCode算法代码分享
2020/08/11 Javascript
jquery UI Datepicker时间控件的使用方法(终结版)
2015/11/07 Javascript
jQuery animate和CSS3相结合实现缓动追逐效果附源码下载
2016/04/18 Javascript
jquery实现全选和全不选功能效果的实现代码【推荐】
2016/05/05 Javascript
node.js 核心http模块,起一个服务器,返回一个页面的实例
2017/09/11 Javascript
Vue组件和Route的生命周期实例详解
2018/02/10 Javascript
nodejs+mongodb aggregate级联查询操作示例
2018/03/17 NodeJs
JS实现字符串中去除指定子字符串方法分析
2018/05/17 Javascript
vue2 v-model/v-text 中使用过滤器的方法示例
2019/05/09 Javascript
Node.js Domain 模块实例详解
2020/03/18 Javascript
[44:22]完美世界DOTA2联赛循环赛 FTD vs PXG BO2第一场 11.01
2020/11/02 DOTA
python+matplotlib绘制简单的海豚(顶点和节点的操作)
2018/01/02 Python
python奇偶行分开存储实现代码
2018/03/19 Python
python pyinstaller打包exe报错的解决方法
2019/11/02 Python
Python turtle库绘制菱形的3种方式小结
2019/11/23 Python
tensorflow 查看梯度方式
2020/02/04 Python
使用pygame编写Flappy bird小游戏
2020/03/14 Python
解释一下Windows的消息机制
2014/01/30 面试题
实习自荐信
2013/10/13 职场文书
有关打架的检讨书
2014/01/25 职场文书
音乐教学反思
2014/02/02 职场文书
创业者是否需要商业计划书?
2014/02/07 职场文书
《蜗牛的奖杯》教后反思
2014/04/24 职场文书
2014银行授权委托书样本
2014/10/04 职场文书
教师节表彰会主持词
2015/07/06 职场文书
环保建议书作文300字
2015/09/14 职场文书
实例讲解Python中sys.argv[]的用法
2021/06/03 Python
SQL Server作业失败:无法确定所有者是否有服务器访问权限的解决方法
2021/06/30 SQL Server
MYSQL 的10大经典优化案例场景实战
2021/09/14 MySQL
德生BCL3000抢先使用感受和评价
2022/04/07 无线电