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