最通俗易懂的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移动div层-javascript 拖动层
Mar 22 Javascript
在IE 浏览器中使用 jquery的fadeIn() 效果 英文字符字体加粗
Jun 02 Javascript
javascript模版引擎-tmpl的bug修复与性能优化分析
Oct 23 Javascript
ExtJS下 Ext.Direct加载和提交过程排错小结
Apr 02 Javascript
js跑马灯代码(自写)
Apr 17 Javascript
在页面上用action传递参数到后台出现乱码的解决方法
Dec 31 Javascript
使用JS或jQuery模拟鼠标点击a标签事件代码
Mar 10 Javascript
js实现图片上传并正常显示
Dec 19 Javascript
深入理解JS函数的参数(arguments)的使用
May 28 Javascript
JavaScript实现左右下拉框动态增删示例
Mar 09 Javascript
小程序采集录音并上传到后台
Nov 22 Javascript
AJAX实现省市县三级联动效果
Oct 16 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
这部好评如潮的动漫 知名梗频出 但是画风劝退很多人
2020/03/08 日漫
用PHP生成自己的LOG文件
2006/10/09 PHP
PHP 修复未正常关闭的HTML标签实现代码(支持嵌套和就近闭合)
2012/06/07 PHP
php实现获取局域网所有用户的电脑IP和主机名、及mac地址完整实例
2014/07/18 PHP
YII2 实现多语言配置的方法分享
2017/01/11 PHP
cakephp2.X多表联合查询join及使用分页查询的方法
2017/02/23 PHP
解决出现SoapFault (looks like we got no XML document)的问题
2017/06/24 PHP
PHP abstract 抽象类定义与用法示例
2018/05/29 PHP
一些常用的Javascript函数
2006/12/22 Javascript
JavaScript 捕获窗口关闭事件
2009/07/26 Javascript
jquery 新浪网易的评论块制作
2010/07/01 Javascript
js中有关IE版本检测
2012/01/04 Javascript
通过正则格式化url查询字符串实现代码
2012/12/28 Javascript
JQEasy-ui在IE9以下版本中二次加载的问题分析及处理方法
2014/06/23 Javascript
js判断当前页面用什么浏览器打开的方法
2016/01/06 Javascript
js实现固定宽高滑动轮播图效果
2017/01/13 Javascript
Angular实现下拉框模糊查询功能示例
2018/01/03 Javascript
Vue 数组和对象更新,但是页面没有刷新的解决方式
2019/11/09 Javascript
[53:10]Secret vs Pain 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
python爬虫入门教程--HTML文本的解析库BeautifulSoup(四)
2017/05/25 Python
Tensorflow 训练自己的数据集将数据直接导入到内存
2018/06/19 Python
pycharm配置当鼠标悬停时快速提示方法参数
2019/07/31 Python
Python 调用 Windows API COM 新法
2019/08/22 Python
PyCharm更改字体和界面样式的方法步骤
2019/09/27 Python
详解python 中in 的 用法
2019/12/12 Python
如何在mac环境中用python处理protobuf
2019/12/25 Python
Python中断多重循环的几种方式详解
2020/02/10 Python
Python交互环境下打印和输入函数的实例内容
2020/02/16 Python
Python xlwings插入Excel图片的实现方法
2021/02/26 Python
如何用H5实现一个触屏版的轮播器的实例
2017/01/09 HTML / CSS
英国知名美妆护肤在线商城:Zest Beauty
2018/04/24 全球购物
法国房车租赁网站:Yescapa
2019/08/26 全球购物
甜品蛋糕店创业计划书范文
2014/02/06 职场文书
软件专业毕业生个人自我鉴定
2014/04/17 职场文书
人大调研汇报材料
2014/08/14 职场文书
Python实现打乒乓小游戏
2021/09/25 Python