TypeScrpt 中变量申明次要有三种形式:var,let 和 const。
var 申明
讲讲 var 的特点
1. 变量晋升
2. 可反复申明,后申明笼罩前申明
3.var 的作用域,来看上面的例子:
function f(flag:boolean) {if(flag) {var x = 10;}
}
f(true); // returns "10"
f(false); // returns "undefined"
能够看到,咱们将变量 X 定义在 if 语句内,然而却能够在 if 语句里面拜访它。这是因为 var 申明能够在蕴含他的函数,模块命名空间或全局作用域外部的任何地位被拜访。此为 var 作用域或函数作用域,函数参数也应用函数作用域。
let 申明
let 与 var 的写法统一
let hello = "Hello!";
次要区别在语义上。
块作用域
当用 let 申明一个变量,它应用的是词法作用域或块作用域。var 申明的变量能够在蕴含他们的函数外拜访,与 var 不同的是,块作用域变量在蕴含他们的块或 for 循环之外是不能拜访的。
来看上面的例子:
function f(flag:boolean) {
let a = 100;
if(flag) {
let b = a + 1;
return b;
}
return b; // 报错
}
咱们在函数外部用 let 定义了 a,b 两个变量。a 的作用域是 f 函数体内,而 b 的作用域是 if 语句内,if 语句内能够拜访 a,然而 if 语句外无法访问到 b,因而在 if 语句外拜访 b 会报错。
块级作用域的特点之一是没有变量晋升,也就是不能在被申明之前读写,这也是与 var 不同的中央。
const 申明
const 也是申明变量的一种形式。
const Π = 3.14
const 领有与 let 雷同的作用域规定,然而不能对他们从新赋值。
const age = 18;
const Tom = {
name: "Tom",
age: age
};
// 报错
Tom = {
name: "Jerry",
age: age
};
//ok
Tom.name = "tom";
Tom.age--;
通过以上例子不难看出,在给 Tom 从新赋值对象时报错,然而批改 Tom 的属性值时失常运行。这是因为 const 定义的变量的不能批改的含意是不能批改变量的援用。
如果 const 定义的变量为简略数据类型:字符串、数字等类型,不能批改;如果 const 定义的变量为简单数据类型:对象、数组等,不能批改其援用,但能够批改其属性的值。
解构
解构赋值语法是一种 Javascript 表达式。能够将数组中的值或对象的属性取出,赋值给其余变量。
构造数组
let array = [1, 2];
let [first, second] = array;
console.log(first); // 1
console.log(second); // 2
这里通过解构创立了 first 和 second 两个变量。
作用域函数参数:
function f([first, second]: [number, nnumber]) {console.log(first);
console.log(second);
}
f([1,2])
也能够在数组里应用 … 开展操作符创立残余变量:
let [first, ...rest] = [1, 2, 3, 4];
console.log(first); // 1
console.log(rest); // [2, 3, 4]
也能够疏忽不关怀的尾随元素或其余元素:
let [first] = [1, 2, 3, 4];
console.log(first); // 1
let [,second,, last] = [1, 2, 3, 4];
console.log(second); // 2
console.log(last); // 4
解构对象
let o = {
a: "foo",
b: 5,
c: "bar"
};
let {a, b} = o;
这里通过 o.a 和 o.b 创立了 a 和 b, 能够疏忽不须要的属性,例如这里的 c。
在后面咱们讲到,能够对没有申明的数组解构,对象同样也能够。
({a, b} = {a:"bar", b:10});
这里要留神,在 javascript 中通常会以 { 起始的语句解析为一个块,因而咱们在这里用括号将其括起来。
也能够用 … 开展操作符创立残余变量:
let {a, ...restProperty} = o;
let rest = restProperty.b + restO=Property.c.length;
属性重命名
能够给属性以不同的名字:
let {a: newName1, b: newName2} = o;
这里咱们将 a 重命名为 newName1,b 重命名为 newName2, 能够将 a 作为 newName1,b 作为 newName2。
须要留神的是,这里的: 是重命名的作用,并不是批示类型,如果要同时指定类型,依然须要在气象写上残缺的模式。
let {a:newName1, b: newName2}: {a:string, b: number} = o;
默认值
在函数调用时,有时咱们并不会传所有参数,此时,能够为函数参数给默认值。
function f(args: {a: string, b?: number}) {let { a, b = 18} = args;
}
这里,咱们给函数参数 b 给定了默认值为 18。
开展
开展操作符与解构相同,它能够将一个数组开展为另一个数组,或将一个对象开展为另一个对象。例如:
let first = [1,2];
let second = [3,4];
let bothPlus = [0, ...first, ...second,5];
这里,bothPlus 的值为 [0, 1 ,2, 3, 4, 5], 开展操作创立了 first 和 second 的一份浅拷贝,他们不会被开展操作所扭转。
同解构一样,也能够开展对象:
let cat = {name: "Tom", age: 18};
let Tom = {...cat, gender: male};
Tom 的值为{name: “Tom”, age: 18, gender: male}, 对象的开展较于数组的开展更为简单。同数组的开展一样,它从左至右进行,但后果仍为对象。这意味着,开展对象前面的属性会笼罩后面的属性。
let cat = {name: "Tom", age: 18, gender: female};
let Tom = {...cat, gender: male};
这里,Tom 的值为 {name: “Tom”, age: 18, gender: male}。
另外,开展对象,仅蕴含对象本人的可枚举属性。因而,当开展对象是,会失落对象自身的办法:
class Cat {
name: "Tom";
hunt() {console.log("抓老鼠~");
}
}
let Tom = new Cat();
let smallTom = {...Tom};
console.log(smallTom.name); // Tom
smallTom.hunt; // 报错
其次,Typescript 编译器不容许开展泛型函数上的类型参数。