手记

【前端骚操作】var,let与const的恩怨情仇

var,let与const的恩怨情仇

以下内容源自《深入理解 ES6》的书,有更多兴趣的建议看看。

三角关系其实很清晰

js:喵蛋,你们谁敢说变量声明比我“优秀”的?

php:世界“第一”的我表示,不敢。

java:世界最“牛”的我表示,不敢。

python:世界最“简单”的我表示,不敢。

c:傻逼……


var

谨记一点:var 声明的变量永远声明在当前所在 函数 的作用域内,非函数作用域内声明还是被当做声明在所在函数内,如下伪代码:

function() {
    var a = 1

    if(any) {
        var b = 1
        console.log(a, b,) // 1, 1
    } else {
        console.log(a, b) // 1, undefined,注意不是not defined
    }

    console.log(b) // undefined
}

其中 var b = 1 被分解为:var b; b = 1,而 var b 部分被提升(hoisting,跟我读:好意思听?)到 function 里面了,明白?如下:

function() {
    var a
    var b
    a = 1

    if(any) {
        b = 1
        console.log(a, b,) // 1, 1
    } else {
        console.log(a, b) // 1, undefined,注意不是not defined
    }

    console.log(b) // undefined
}

与 window 的关系

在浏览器环境下,全局默认有个 window 对象,因为 var 的 hoisting 存在,会使得 var 个东西变成 window 的,这不是坏事,很多人已经习惯这么干了,比如:

var test = 1
window.test // 1

if(1) {
    var test1 = 1
}

window.test1 // 1

这个好处是很方便获取变量,坏处就是容易把 window 的自带属性给覆盖了,如下:

var RegExp = '1'
window.RegExp // 1

大哥,RegExp 是很重要的对象好吗?


let

首先,let 就锁作用域了,跟 var 不同,不会 hoisting(读一遍),而且是根据代码块,而不是函数作用于,也就是说,if,for 等等都会锁作用域,如下伪代码:

function() {
    let a = 1

    if(any) {
        let b = 1
        console.log(a, b,) // 1, 1
    } else {
        console.log(a, b) // 1, not defined,其实这里是报错……
    }

    console.log(b) // not defined,其实这里是报错……
}

其次,let 不允许同作用域内重复声明,注意,同作用域,伪代码:

function() {
    let a = 1
    let a = 2 // 报错

    if(any) {
        let a = 3 // 没错,此a非彼a了,当前代码块内用到的都是这个a
    }
}

暂时性死区

temporal dead zone,TDZ

这个名字非常非常的头(shuai)疼(qi),看这个代码:

if(1) {
    console.log(typeof a) // undefined,hoisting,ok?
    var a = 1
}

if(1) {
    console.log(typeof a) // 暂时性死区
    let a = 1
}

console.log(typeof a) // undefined
if(1) {
    let a =  1
}

头大不?其实这个头(shuai)疼(qi)的名词解释的反而挺到位的。

var 不解释了,先解释第三个,就是常规的使用 typeof 检测变量属性,如果变量未申明,返回undefined,这是正常的;但是在 let 和 const(没错,const一样)所在作用域内,因为 let 和 const 的存在,导致其申明的变量被锁死,在申明前被调用的话,呵呵,不好意思,就算你是 typeof 大哥也没用,报错。

注意,说的是被 let 和 const 申明的才会被锁死,没被绑定的是常规处理,如下:

if(1) {
    console.log(typeof jhdskfkjfhdkj) // undefined
    console.log(typeof a) // 暂时性死区
    let a = 1
}

与 window 的关系

没关系。

let RegExp = 1
window.RegExp // ƒ RegExp() { [native code] }
RegExp // 1

const

constant(跟我读:康斯顿~),就是不变的量,很多人容易忘记初始化,然后报错了再来添加初始值,这里脑子稍微过一下就可以记住:

假如不赋值能成功(说了假如),那就是 undefined,你没事创建个 undefined 来展示代码有多l ow 么?然后你又后面修改,但是本身人家就不能修改,所以一定需要初始化赋值,这样逻辑就通了……

恩,对了,他的作用域跟 let 一样一样的。没错,重复声明也不行。

之前说过,const 比较坑的就是,如果值是对象,对象的属性却是可以修改的……伪代码:

const a = {
    b: 1
}

a = {} // 报错

a.b = 2 // 没错

暂时性死区

与 let 一样(const:喂喂喂,啥都跟 let 一样,搞得我好像它小弟一样。),但是由于 const 的不可变性,就不要想着用来搞常规循环那个啥了,这个跟 let 不一样。

常规循环就是 for(let i = 0; i < x.length; i ++) {} 这个,for in 和 for of 中 const 是可以用的,因为每次都是不同的嘛。

与 window 的关系

与那谁(let)一样。


用谁的问题

之前我文章写的是尽量使用 let,恩,现在我改了,这个真不是这个书的事情……

默认使用 const,除非是一定需要变动的,则使用 let,极特殊的情况下并且你能控制 var,再考虑使用 var。


欢迎关注,如有需要 Web,App,小程序,请留言联系。

0人推荐
随时随地看视频
慕课网APP