变量声明
某些内容省略。想了解更深请前往官方文档学习。
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
通常来说会把默认值放在前边,用于被一些后来设定的属性所覆盖。