最通俗易懂的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之更有效率的字符串替换
Aug 02 Javascript
JavaScript 嵌套函数指向this对象错误的解决方法
Mar 15 Javascript
关于jquery input textare 事件绑定及用法学习
Apr 03 Javascript
开源免费天气预报接口API及全国所有地区代码(国家气象局提供)
Dec 26 Javascript
微信小程序开发之从相册获取图片 使用相机拍照 本地图片上传
Apr 18 Javascript
关于页面刷新vuex数据消失问题解决方案
Jul 03 Javascript
微信小程序实现文字从右向左无限滚动
Nov 18 Javascript
利用原生JS实现data方法示例代码
May 28 Javascript
如何使用Node.js爬取任意网页资源并输出PDF文件到本地
Jun 17 Javascript
Vue-drag-resize 拖拽缩放插件的使用(简单示例)
Dec 04 Javascript
Vue项目中数据的深度监听或对象属性的监听实例
Jul 17 Javascript
js实现数字跳动到指定数字
Aug 25 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笔试题
2009/08/04 PHP
PHP5中Cookie与 Session使用详解
2013/04/30 PHP
php中get_defined_constants函数用法实例分析
2015/05/12 PHP
PHP实现的QQ空间g_tk加密算法
2015/07/09 PHP
Zend Framework动作助手Url用法详解
2016/03/05 PHP
Javascript的一种模块模式
2008/03/22 Javascript
jQuery截取指定长度字符串代码
2014/08/21 Javascript
jQuery事件绑定与解除绑定实现方法
2015/04/15 Javascript
JavaScript截取、切割字符串的技巧
2016/01/07 Javascript
JS中递归函数
2016/06/17 Javascript
jquery获取链接地址和跳转详解(推荐)
2017/08/15 jQuery
javascript观察者模式实现自动刷新效果
2017/09/05 Javascript
详解vue.js根据不同环境(正式、测试)打包到不同目录
2018/07/13 Javascript
vue v-for 使用问题整理小结
2019/08/04 Javascript
微信小程序 腾讯地图SDK 获取当前地址实现解析
2019/08/12 Javascript
vue基于v-charts封装双向条形图的实现代码
2019/12/09 Javascript
Python定时器实例代码
2017/11/01 Python
Python排序算法之选择排序定义与用法示例
2018/04/29 Python
利用python如何处理nc数据详解
2018/05/23 Python
Python 正则表达式匹配字符串中的http链接方法
2018/12/25 Python
django query模块
2019/04/20 Python
python 实现查找文件并输出满足某一条件的数据项方法
2019/06/12 Python
如何利用Python开发一个简单的猜数字游戏
2019/09/22 Python
python在不同条件下的输入与输出
2020/02/13 Python
django rest framework 自定义返回方式
2020/07/12 Python
PyQt中使用QtSql连接MySql数据库的方法
2020/07/28 Python
html5使用canvas实现跟随光标跳动的火焰效果
2014/01/07 HTML / CSS
阿根廷网上配眼镜:SmartBuyGlasses阿根廷
2016/08/19 全球购物
英国的潮牌鞋履服饰商店:size?
2019/03/26 全球购物
MAC Cosmetics巴西官方网站:M·A·C彩妆
2019/04/18 全球购物
美国智能家居专家:tink
2019/06/04 全球购物
美国唇部护理专家:Sara Happ
2019/06/19 全球购物
编写类String 的构造函数、析构函数和赋值函数
2012/09/09 面试题
中学优秀班主任事迹材料
2014/05/01 职场文书
三十年再续同学情倡议书
2019/11/27 职场文书
vue实现同时设置多个倒计时
2021/05/20 Vue.js