变量声明

某些内容省略。想了解更深请前往官方文档学习。

var声明

熟悉JavaScript的都会知道,var声明的变量会有作用域的一些问题。
官方文档给了例子,作者精简一下给出内容如下:

作用域规则
function f(shouldInitialize: boolean) {    if (shouldInitialize) {        var x = 10;    }    return x;}

变量 x 是定义在if语句里面,但是我们却可以在语句的外面访问它。
var声明可以在包含它的函数,模块,命名空间或全局作用域内部任何位置被访问,称为var作用域或函数作用域

捕获变量怪异之处
for (var i = 0; i < 10; i++) {    setTimeout(function() { console.log(i); }, 100 * i);} //打印结果全部为9

过去咱们用闭包来解决这个问题

for (var i = 0; i < 10; i++) {  (function(i){    setTimeout(() => {      console.log(i)    }, 100*i);  })(i)}

因为以上一些奇怪的现象,所以就引出let的诞生。

let声明

除了名字不同外, let与var的写法一致。

作用域规则

{}为let的作用域,外面是不能访问的。

重定义及屏蔽

var声明时,它不在乎你声明多少次;你只会得到1个。
let重复声明就会报错。

再来看看之前的一段代码

for (var i = 0; i < 10; i++) {    setTimeout(function() { console.log(i); }, 100 * i);} //打印结果全部为9

用let就不会出现var的结果

for (let i = 0; i < 10; i++) {    setTimeout(function() { console.log(i); }, 100 * i);} //打印结果为0~9

const声明

const声明是声明变量的另一种方式。
const声明的是常量,不能对它们重新赋值。

解构

这个工作中用的很多很多很多。

数组解构
let input = [1, 2];let [first, second] = input;console.log(first); // 输出 1console.log(second); // 输出 2
let [first, ...rest] = [1, 2, 3, 4];console.log(first); // 输出 1console.log(rest); // 输出 [ 2, 3, 4 ]

当然,由于是JavaScript, 你可以忽略你不关心的尾随元素:

let [first] = [1, 2, 3, 4];console.log(first); // 输出 1

或其它元素:

let [, second, , fourth] = [1, 2, 3, 4];
对象解构
let o = {    a: "foo",    b: 12,    c: "bar"};let { a, b } = o;console.log(a) // "foo"console.log(b) // "bar"
属性重命名
let { a: newName1, b: newName2 } = o;

可以读作为“a作为newName1
就像如下表达方式

let newName1 = o.a;let newName2 = o.b;

令人困惑的是,这里的冒号不是指示类型的。 如果你想指定它的类型, 仍然需要在其后写上完整的模式。

let {a, b}: {a: string, b: number} = o;
默认值
// 传入的对象中,b 属性有可能不存在// type C = { a: string, b?: number }function keepWholeObject(wholeObject: { a: string, b?: number }) {  // 所以解构时要为 b 属性提供默认值  let { a, b = 1000 } = wholeObject  console.log(a, b)}
函数声明
function foo({ a, b = 0 } = { a: '' }): void {  console.log(a, b)}foo({ a: 'yes' }) // 传入的对象,没有 b 属性,但好在 b 在解构时提供了默认值 0foo() //不传参数时,默认从 { a: '' } 解构foo({}) // 报错!因为类型不匹配。传入空对象,虽然 b 属性有默认值 0,但是 a 属性无从得知
展开

数组的展开

let first = [1, 2]let second = [3, 4]let bothPlus = [0, ...first, ...second, 5]console.log(bothPlus) // [0, 1, 2, 3, 4, 5]

对象的展开

let defaults = {  food: 'apple',  price: '$10',  total: 50}let search = { ...defaults, food: 'rich' }console.log(search)// {food: "rich", price: "$10", total: 50} 右边的同名属性 food 覆盖了左边展开后的属性 food

通常来说会把默认值放在前边,用于被一些后来设定的属性所覆盖。