javascript声明提升

前段时间阅读一本书《ESCMScript 6入门》,其中一章关于”let和const命令”有一段代码

var tmp = new Date()
function f(){
    console.log(tmp)
    if(false){
        var tmp = 'hello world'
    }   
}

关于变量声明提升,思量许久,写了以下理解。

这段代码看似简单,其内部隐藏着重要的知识点“变量提升”这一现象。一般理解,调用f函数tmp要么打印出日期,要么打印出undefined,结果为后者。为何?

书本上仅仅这么说明:原因在于变量提升,导致内层tmp变量覆盖了外层tmp变量

仅仅理解这句话并不能清楚的知道为何?

再来看下面的代码:

function f(){
    var item1 = 1;
    var item2 = 'str';
    var item = [1]
}

经过编译器预处理类似变成:

function f(){
    var item1,item2,item3;
    item1 = 1;
    item2 = 'str'
    item3 = [1]
}

经过编译器处理只会将所有的变量进行统一的声明处理,所以,案例中经典的代码可以改为:

var tmp = new Date();
function f(){
    var tmp;
    console.log(tmp);
    if(false){
        var tmp = 'hello world';
    }   
}

总结:变量提升分为声明提升和定义提升,赋值或者初始话并不会被提升,而代码中出现if条件语句,虽然代码不会进入那个片段,但是编译器会预处理里面的代码,将声明tmp提升到f函数的最顶层,之所以覆盖全局,是因为内部已经声明了tmp变量,将外部全局变量对f函数的tmp的搜索值屏蔽,因函数存在声明,tmp变量就不再往上层去搜索值(原型链搜索),这与对象的原型方法搜索类似。

2018-09-06

上文是我在两个月前写的let变量提升的理解,但是自从面试之后,发现不仅仅那么简单,面试官这样问我:var存在变量声明提升,那let会么?按照MDN文档的解释,因为let存在暂时性死区,所以无法进行变量声明提升。但真的是这样简单的理解了么,下面我来把真正的原因讲一下。

在MDN文档描述了let的知识,总结有一下三条:

  1. let声明变量的作用是块级的;
  2. let不能重复声明一已经存在的变量;
  3. let存在暂时性死区,变量声明不会被提升。

虽然你理解了上面三个总结,但是你的理解和对let的全面理解并不深刻。

let是否存在变量提升问题?

其实所有声明变量的关键字,都存在变量声明提升这个功能,只不过有些可以表现出这个特性,如var,有些不能,如let,为什么let不能呢,暂时性死区又怎么作用于它呢?

MDN文档在let上前后进行了两次修改,所以其作者也是举起不定,我们翻看es文档,会发现一段话:
The environment of with statements cannot contain any lexical declaration so it doesn't need to be checked for var/let hoisting conflicts
这句话证明了let存在变量提升。提升不是一个技术名称,js变量被声明的过程:创建、初始化、赋值。

  • var在创建和初始化的过程中都被提升;
  • let在创建会被提升,而初始化没用被提升,因为暂时性死区(变量在未使用之前,不能使用该变量);
  • 函数创建、初始化和赋值都被提升; const只有创建和初始化过程,没有赋值过程。

总结:

  • let 具有变量提升过程,但不表现这个过程,因为存在暂时性死区;
  • let 创建会被提升,但初始化不能被提升;
  • 所有变量声明的关键字操作都存在变量提升这个过程,只是因为不同情况和性质导致是否需要表现出来。

(文章结合自己思考和参考一些资料,如有侵权请联系本人,会尽快处理)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值