最通俗易懂的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 相关文章推荐
jsTree树控件(基于jQuery, 超强悍)[推荐]
Sep 01 Javascript
JS 文件传参及处理技巧分析
May 13 Javascript
BootStrap智能表单实战系列(九)表单图片上传的支持
Jun 13 Javascript
文本框只能输入数字的js代码(含小数点)
Jul 10 Javascript
多个上传文件用js验证文件的格式和大小的方法(推荐)
Mar 09 Javascript
bootstrap警告框示例代码分享
May 17 Javascript
jQuery查找和过滤_动力节点节点Java学院整理
Jul 04 jQuery
vue+axios新手实践实现登陆的示例代码
Jun 06 Javascript
layui操作列按钮个数和文字颜色的判断实例
Sep 11 Javascript
js 动态校验开始结束时间的实现代码
May 25 Javascript
vue2.0实现列表数据增加和删除
Jun 17 Javascript
vue路由实现登录拦截
Mar 24 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
破解图片防盗链的代码(asp/php)测试通过
2010/07/02 PHP
php获取url参数方法总结
2014/11/13 PHP
PHP Cookie学习笔记
2016/08/23 PHP
基于JQuery的cookie插件
2010/04/07 Javascript
JS弹出层的显示与隐藏示例代码
2013/12/27 Javascript
事件委托与阻止冒泡阻止其父元素事件触发
2014/09/02 Javascript
js获取form的方法
2015/05/06 Javascript
JavaScript DOM 学习总结(五)
2015/11/24 Javascript
AngularJs 弹出模态框(model)
2016/04/07 Javascript
js正则表达式注册页面表单验证
2016/10/11 Javascript
AngularJS变量及过滤器Filter用法分析
2016/11/22 Javascript
使用ES6语法重构React代码详解
2017/05/09 Javascript
详解NODEJS的http实现
2018/01/04 NodeJs
详解Vue.js iview实现树形权限表(可扩展表)
2018/09/30 Javascript
vue通过cookie获取用户登录信息的思路详解
2018/10/30 Javascript
如何在Node和浏览器控制台中打印彩色文字
2020/01/09 Javascript
React中获取数据的3种方法及优缺点
2020/02/18 Javascript
python中精确输出JSON浮点数的方法
2014/04/18 Python
简单介绍Python中的len()函数的使用
2015/04/07 Python
tensorflow: 查看 tensor详细数值方法
2018/06/13 Python
Python统计纯文本文件中英文单词出现个数的方法总结【测试可用】
2018/07/25 Python
python hook监听事件详解
2018/10/25 Python
python web框架中实现原生分页
2019/09/08 Python
Django 路由层URLconf的实现
2019/12/30 Python
Django values()和value_list()的使用
2020/03/31 Python
解决json中ensure_ascii=False的问题
2020/04/03 Python
基于tf.shape(tensor)和tensor.shape()的区别说明
2020/06/30 Python
Python基于template实现字符串替换
2020/11/27 Python
Python创建文件夹与文件的快捷方法
2020/12/08 Python
Pycharm制作搞怪弹窗的实现代码
2021/02/19 Python
普天C++笔试题
2016/03/20 面试题
后勤采购员岗位职责
2013/12/19 职场文书
2015年英语教师工作总结
2015/05/20 职场文书
Python打包exe时各种异常处理方案总结
2021/05/18 Python
html5表单的required属性使用
2021/07/07 HTML / CSS
使用Python+OpenCV进行卡类型及16位卡号数字的OCR功能
2021/08/30 Python