变量声明

letconst 是JavaScript新出的两个变量声明的方式。前面说过letvar类似,但是它们的作用域是不一样的。

关于作用域,在ES6之前的Javascript中,函数体是唯一能能够创建新作用域的地方。那时候没有let,用var声明的变量,作用域要么是全局,要么是函数体,没有块级的作用域(块作用域变量在包含它们的块外部或for循环外部是不能被访问的)。而新版的Javascript引入了let关键字,用以声明一个块级域的本地变量,这样能避免一些问题。

至于const,它的作用域和let一样,但是是声明创建一个只读常量,这里要注意一下,这并不意味着该常量指向的值不可变,而是该常量只能被赋值一次!

举个例子:

// numLivesForCat的值不能再变了
const numLivesForCat = 9;
const kitty = {
    name: "Aurora",
    numLives: numLivesForCat,
}

// 错误,kitty指向的对象不能变
kitty = {
    name: "Danielle",
    numLives: numLivesForCat
};

// 没问题,对象的属性可以变化
kitty.name = "Rory";
kitty.name = "Kitty";
kitty.name = "Cat";
kitty.numLives--;

另外,使用const定义常量时,一定要初始化。

Typescript作为Javascript的超集,自然也是支持letconst的。

该用哪个

const没什么好说的,你需要常量就用它,不需要就不用。但是letvar要比较一下。

使用var声明变量时,不管你声明多少次,你得到的只有一个变量,而使用let时,同一个变量名在同一作用域内声明一次以上会报错。

使用var时很容易出bug,比如:

function sumMatrix(matrix: number[][]) {
    var sum = 0;
    for (var i = 0; i < matrix.length; i++) {
        var currentRow = matrix[i];
        for (var i = 0; i < currentRow.length; i++) {
            sum += currentRow[i];
        }
    }

    return sum;
}

里层for循环中的i会覆盖外层的i,因为i引用的都是相同的函数作用域内的变量。

但是如果把var换成let,内层的for循环自己是一个块级作用域,会屏蔽外部的作用域中的相同名字的变量,所以这两个i会井水不犯河水。

另外,因为var是函数作用域,所以对于一个var声明的变量,你可以先使用再声明:

bla = 2;
var bla;
// ...

// 可以理解为下面这样:

var bla;
bla = 2;

引用一段mozilla文档中的话:

由于变量声明(以及其他声明)总是在任意代码执行之前处理的,所以在代码中的任意位置声明变量总是等效于在代码开头声明。这意味着变量可以在声明之前使用,这个行为叫做“hoisting”。

嗯,使用var时,这叫变量声明提升,但是如果你使用let时也这样做,这叫错误! 块级作用域的变量的一个特点是,它们不能在被声明之前使用

最后,建议尽量用let替换var

本文参考:


er3456qi
450 声望2 粉丝

是个好人