我眼中的var和let

JavaScript中Var与Let的比较已经是老生常谈的问题了,那今天我们来聊聊这两个关键字

变量提升

首先就是变量提升了,var可以变量提升,而let不行,我认为这是个好事。

说到变量提升,我们再来聊聊function

function test() {
    console.log('a')
}

test ()

function test() {
    console.log('b')
}

test()

// output b b
var test = 1
function test() {
    console.log('a')
}

test ()


// TypeError: test is not a function

// 等价于如下代码
var test
function test() {
    console.log('a')
}
test = 1
test()

这涉及到functionvar的变量提升的区别了,var中的变量提升只会提升变量声明,而不会提前赋初始值,但是function则会在提升时就指向了那个函数,所以function显然更具迷惑性

这里可能会有人问变量提升和函数提升的先后顺序了,其实我认为谁先谁后无所谓,因为var关键字提升时只声明不赋值,并且可以重复声明,所以不论谁先谁后,最后的表现形式都可以将function写在后面。这点可能需要大家思考一下

块级作用域

{
    var a = 1
    let b = 2
}
console.log(a)
console.log(b)

// output: 
// 1
// ReferenceError: b is not define

let声明的变量只存在于块级作用域内,所以如下代码

for (let i = 0; i < 10; i++) {
    setTimeout(() => {
        console.log(i)
    }, 1000)
}

// output: 0123456789

为什么呢?因为每次循环变量i都不一样。不相信?我们来验证一下

let map = {}
for (let i = 0; i < 10; i++) {
    map[i] = {
        add() {
            i++
        },
        print() {
            console.log(i)
        }
    }
}

map[0].print()
map[1].print()
map[0].add()
map[0].print()
map[1].print()

// output: 0 1 1 1

我们使用闭包让这些变量不会被回收,虽然都是i但是他们是不同的

暂时性死区

let声明的变量不允许再次声明,也不允许在声明前使用(不仅仅因为不会变量提升)

{
    let a = 1
    b = 2
    var a = 3  // SyntaxError: Identifier 'a' has already been declared
}

{
    console.log(b)
    console.log(a)  // a is not define
    let a = 1
    var b = 2
}

{
    console.log(typeof b)
    console.log(typeof a)  // a is not define
    let a = 1
}

二者在Nodejs和浏览器环境中的区别

观察如下代码在Nodejs中和浏览器中的区别

{
    let a = 1
    b = 2
    var c = 3
    debugger
}

/*
Nodejs
由于let声明的变量具有块级作用域,所以a在Block下
由于b未声明,所以默认绑定在global下
c使用了var声明,又不具有块级作用域,所以绑定在该模块Local下
*/

/*
浏览器
由于let声明的变量具有块级作用域,所以a在Block下
由于b未声明,所以默认绑定在global下,浏览器中为window
c使用了var声明,又不具有块级作用域,而浏览器中又没有模块,所以绑定在global下,浏览器中为window
*/

Nodejs中

Nodejs

浏览器中

image

d = 6
var e = 4
let f = 5
debugger

/*
Nodejs
由于d没有声明,所以默认绑定在global下
e使用var声明,所以绑定在local下
f使用let声明,也绑定在local下
*/
/*
浏览器中
由于d未声明,所以默认绑定在global下,浏览器中为window
e使用var声明,浏览器中没有模块,所以也绑定在global中,浏览器中为window
f使用let声明,而let声明的变量是不会默认绑定在global下的,所以f绑定在Script下
*/

Nodejs中

image

浏览器中

image
image

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值