最通俗易懂的javascript变量提升详解

 更新时间:2017年08月05日 09:14:23   投稿:jingxian  
下面小编就为大家带来一篇最通俗易懂的javascript变量提升详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

如下所示:

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变量提升详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 小程序组件之自定义顶部导航实例

    小程序组件之自定义顶部导航实例

    这篇文章主要给大家介绍了关于小程序组件之自定义顶部导航的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用小程序具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06
  • uniapp页面跳转的五种方式总结

    uniapp页面跳转的五种方式总结

    这篇文章主要给大家介绍了关于uniapp页面跳转的五种方式,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2023-03-03
  • JS实现在状态栏显示打字效果完整实例

    JS实现在状态栏显示打字效果完整实例

    这篇文章主要介绍了JS实现在状态栏显示打字效果的方法,涉及JavaScript中字符遍历结合时间函数对状态栏显示进行操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-11-11
  • JS模仿编辑器实时改变文本框宽度和高度大小的方法

    JS模仿编辑器实时改变文本框宽度和高度大小的方法

    这篇文章主要介绍了JS模仿编辑器实时改变文本框宽度和高度大小的方法,涉及javascript鼠标事件及页面元素样式的动态操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-08-08
  • javascript tips提示框组件实现代码

    javascript tips提示框组件实现代码

    一个简单的类似title的提示效果,但现实内容可以很丰富,以上js另存为tip.js,下面是使用的demo。
    2010-11-11
  • 微信小程序之video组件视频播放

    微信小程序之video组件视频播放

    video控件是微信小程序提供的系统组件之一,用于实现播放视频的功能,这篇文章主要给大家介绍了关于微信小程序之video组件视频播放的相关资料,需要的朋友可以参考下
    2022-04-04
  • 原生js实现九宫格拖拽换位

    原生js实现九宫格拖拽换位

    这篇文章主要为大家详细介绍了原生js实现九宫格拖拽换位,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-01-01
  • JS简单封装的图片无缝滚动效果示例【测试可用】

    JS简单封装的图片无缝滚动效果示例【测试可用】

    这篇文章主要介绍了JS简单封装的图片无缝滚动效果,结合完整实例形式分析了javascript针对图片无缝滚动功能实现的具体操作技巧,包括鼠标事件响应、事件函数及页面元素属性动态变换等相关操作技巧,需要的朋友可以参考下
    2017-03-03
  • JS将时间的标准格式和时间戳格式和2022-01-27 00:00:00(年月日时分秒)格式相互转换(最新推荐)

    JS将时间的标准格式和时间戳格式和2022-01-27 00:00:00(年月日时分秒)格式相互转换(最新推荐)

    这篇文章主要介绍了JS如何将时间的标准格式和时间戳格式和2022-01-27 00:00:00(年月日时分秒)格式相互转换,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-05-05
  • js 内存释放问题

    js 内存释放问题

    这里之所以使用setTimeout(),因为可以彻底回收当前所有对象,防止变量之间的引用导致释放失败,可以当作一个保障措施,按照道理来说,这里不会执行了。
    2010-04-04

最新评论