乐趣区

TypeScript自学第二章变量声明

变量声明

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

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); // 输出 1
console.log(second); // 输出 2
let [first, ...rest] = [1, 2, 3, 4];
console.log(first); // 输出 1
console.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 在解构时提供了默认值 0
foo() // 不传参数时,默认从 { 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

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

退出移动版