最通俗易懂的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 获取LI里的内容
Dec 17 Javascript
基于Jquery的将DropDownlist的选中值赋给label的实现代码
May 06 Javascript
JS实现悬浮移动窗口(悬浮广告)的特效
Mar 12 Javascript
jQuery随机切换图片的小例子
Apr 18 Javascript
javascript实现避免页面按钮重复提交
Jan 08 Javascript
Bootstrap CSS组件之导航(nav)
Dec 17 Javascript
JS填写银行卡号每隔4位数字加一个空格
Dec 19 Javascript
原生JS实现《别踩白块》游戏(兼容IE)
Feb 20 Javascript
Angular2 路由问题修复详解
Mar 01 Javascript
layui表格设计以及数据初始化详解
Oct 26 Javascript
vue实现数据控制视图的原理解析
Jan 07 Javascript
vue+element-ui JYAdmin后台管理系统模板解析
Jul 28 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
zen cart新进商品的随机排序修改方法
2010/09/10 PHP
xml在joomla表单中的应用详解分享
2012/07/19 PHP
php像数组一样存取和修改字符串字符
2014/03/21 PHP
php ImageMagick windows下安装教程
2015/01/26 PHP
PHP实现数组转JSon和JSon转数组的方法示例
2018/06/14 PHP
根据经纬度计算地球上两点之间的距离js实现代码
2013/03/05 Javascript
辨析JavaScript中的Undefined类型与null类型
2016/05/26 Javascript
jQuery EasyUI常用数据验证汇总
2016/09/18 Javascript
js仿新浪微博消息发布功能
2017/02/17 Javascript
js调用刷新界面的几种方式
2017/05/03 Javascript
React+react-dropzone+node.js实现图片上传的示例代码
2017/08/23 Javascript
详解如何在vue项目中引入elementUI组件
2018/02/11 Javascript
JS+HTML5 Canvas实现简单的写字板功能示例
2018/08/30 Javascript
服务端预渲染之Nuxt(使用篇)
2019/04/08 Javascript
vue实现一个6个输入框的验证码输入组件功能的实例代码
2020/06/29 Javascript
antd-DatePicker组件获取时间值,及相关设置方式
2020/10/27 Javascript
vantUI 获得piker选中值的自定义ID操作
2020/11/04 Javascript
python处理中文编码和判断编码示例
2014/02/26 Python
python实现K最近邻算法
2018/01/29 Python
对django中render()与render_to_response()的区别详解
2018/10/16 Python
详解Python中的内建函数,可迭代对象,迭代器
2019/04/29 Python
快速解决docker-py api版本不兼容的问题
2019/08/30 Python
Python数据库小程序源代码
2019/09/15 Python
keras的siamese(孪生网络)实现案例
2020/06/12 Python
python 爬虫爬取京东ps4售卖情况
2020/12/18 Python
Python实现曲线拟合的最小二乘法
2021/02/19 Python
英国户外装备商店:Ultimate Outdoors
2019/05/07 全球购物
会计实习生自我鉴定
2013/12/12 职场文书
暑期研修感言
2014/02/17 职场文书
2014年大学庆元旦迎新年活动方案
2014/03/09 职场文书
岗位职责风险点
2014/03/12 职场文书
爱我中华教学反思
2014/04/28 职场文书
教师群众路线剖析材料
2014/09/29 职场文书
工作能力自我评价2015
2015/03/05 职场文书
Oracle创建只读账号的详细步骤
2021/06/07 Oracle
用Python爬取某乎手机APP数据
2021/06/15 Python