本文只介绍了在ES2015与TypeScript之间变量声明, 解构赋值的区别和新增
如果你不熟悉怎么使用let和const还有解构赋值,请参考阮大神的ES6教程
如果你不清楚为什么不使用var.请参考官方文档http://www.typescriptlang.org/docs/handbook/variable-declarations.html#variable-declarations 的Variable Declarations 章节
function foo() {
// okay to capture 'a'
return a;
}
// illegal call 'foo' before 'a' is declared
// ES2015 runtimes should throw an error here
foo();
let a;
let x = 10;
let x = 20; // error: can't re-declare 'x' in the same scope
function f(x) {
let x = 100; // error: interferes with parameter declaration
}
function g() {
let x = 100;
var x = 100; // error: can't have both declarations of 'x'
}
不同域是允许的(ES2015 & TypeScript)
function f(condition, x) {
if (condition) {
let x = 100;
return x; // 属于if 块级作用域
}
return x; //属于function f () 作用域
}
f(false, 0); // returns '0'
f(true, 0); // returns '100'
嵌套域是允许的(ES2015 & TypeScript)
function sumMatrix(matrix: number[][]) {
let sum = 0;
for (let i = 0; i < matrix.length; i++) {
var currentRow = matrix[i]; //i属于第一个for作用域
for (let i = 0; i < currentRow.length; i++) {
sum += currentRow[i]; //i 属于第二个for作用域
}
}
return sum;
}
(个人意见:为了避免出bug,也让同僚能够更好理解,不推荐使用这种作法)
ES2015和Typecript规则一样,const跟let有相同的作用域规则,只是不能够重新赋值。
有一个特殊类型需要注意: const的内部属性是可编辑的。在TypeScript允许把对象的成员设置成只读(相关例子会在后期补充)
const numLivesForCat = 9;
const kitty = {
name: "Aurora",
numLives: numLivesForCat,
}
// Error
kitty = {
name: "Danielle",
numLives: numLivesForCat
};
// all "okay"
kitty.name = "Rory";
kitty.name = "Kitty";
kitty.name = "Cat";
kitty.numLives--;
let tuple: [number, string, boolean] = [7, "hello", true];
let [a, b, c] = tuple; // a: number, b: string, c: boolean
注意:超过元素的范围会解构报错,但是使用…(展开运算符)不会报错。
let [a, b, c, d] = tuple; // Error, no element at index 3
let [a, b, c, ...d] = tuple; // d: [], the empty tuple
数组和对象都可以用没有声明的变量直接解构赋值(ES2015 && TypeScript)(^ _ ^我也是第一次晓得这个,每次都是同时声明赋值。长知识了!!!)
[a, b] = [1, 2]
({ a, b } = { a: "baz", b: 101 }); //我们不得不用括号将它括起来,因为Javascript通常会将以 { 起始的语句解析为一个块。
let o = {
a: "foo",
b: 12,
c: "bar"
};
let { a: newName1, b: newName2 } = o;
console.log(a); //error
console.log(b); //error
console.log(newName1); // ‘foo’
console.log(newName2 );// 12
可以理解为
let newName1 = o.a;
let newName2 = o.b;
function keepWholeObject(wholeObject: { a: string, b?: number }) {
let { a, b = 1001 } = wholeObject;
}
type C = { a: string, b?: number }
function f({ a, b }: C): void {
console.log(`a: ${a}, b: ${b}`);
}
f({a: 'hello'}) //a: hello, b: undefined
f({a: 'world', b: 1}) //a: world, b: 1
f({a: 'aiyo', b: 1}); //a: aiyo, b: 1
function f({ a, b } = { a: "hello", b: 0 }): void {
console.log(`a: ${a}, b: ${b}`);
}
f(); //a: hello, b: 0
f({a: 'aiyo', b: 1}); //a: aiyo, b: 1
或者
function f({ a, b = 0 } = { a: "hello" }): void {
console.log(`a: ${a}, b: ${b}`);
}
f({a: 'world'}) //a: world, b: 0
f(); //a: hello, b: 0
f({a: 'aiyo', b: 1});//a: aiyo, b: 1
f({}); //error, 如果要赋值调用就必须提供a的值
需要注意一点
不管是ES2015还是TypeScript, 数组的展开是不会覆盖前面相同的值。但是对象的展开会覆盖。
let first = [1, 2];
let second = [5, 4];
let bothPlus = [0, ...first, ...second, 5]; //[0, 1, 2, 5, 4, 5]
let defaults = { food: "spicy", price: "$$", ambiance: "noisy" };
let search = { ...defaults, food: "rich" }; //{food: "rich", price: "$$", ambiance: "noisy"}
let defaults = { food: "spicy", price: "$$", ambiance: "noisy" };
let search = { food: "rich", ...defaults }; // {food: "spicy", price: "$$", ambiance: "noisy"}
不管是ES2015还是TypeScript, 仅包含对象 自身的可枚举属性。 也就意味着当你展开一个对象实例时,你会丢失其方法:
class C {
p = 12;
m() {
}
}
let c = new C();
let clone = { ...c };
clone.p; // ok
clone.m(); // error
目前TypeScript编译器不允许展开泛型函数上的类型参数。当以后版本更新的时候我会回来添加。