字符串的新特性
-
多行字符串
使用``實(shí)現(xiàn)多行字符串
var content = `aaaa
bbbb
ccccc`;
編譯成js代碼為:
var content = "aaaa\nbbbb\nccccc";
-
字符串模板
其實(shí)和多行字符串差不多
var mynane = "jack";
var getName = function () {
return "jack";
}
console.log(`<div>
<span>${mynane}</span>
<span>${getName()}</span>
</div>`);
console.log(`hello${mynane}`);
console.log(`hello${getName()}`);
編譯js代碼:
var mynane = "jack";
var getName = function () {
return "jack";
};
console.log("<div>\n<span>" + mynane + "</span>\n<span>" + getName() + "</span>\n</div>");
console.log("hello" + mynane);
console.log("hello" + getName());
-
自動(dòng)拆分字符串
function test(template, name, age) {
console.log(template);
console.log(name);
console.log(age);
}
var myname = "jack";
var getAge = function () {
return 18;
}
test`hello my name is ${myname},i'm${getAge()}`
打印結(jié)果:
參數(shù)新特性 之 參數(shù)類型
- 參數(shù)類型:在參數(shù)名稱后面使用冒號(hào)來指定參數(shù)的類型
例如:string類型的,當(dāng)賦值number類型時(shí),報(bào)錯(cuò)
string類型的,當(dāng)賦值number類型時(shí),報(bào)錯(cuò)
2.類型推斷機(jī)制
例如:當(dāng)我沒有指定類型時(shí),第一次給變量賦值為string
類型時(shí),當(dāng)我修改這個(gè)變量為number
類型,就會(huì)報(bào)錯(cuò).
類型推斷機(jī)制 -
any
類型
當(dāng)我賦值任何類型時(shí),都不會(huì)報(bào)錯(cuò);
上面的例子,當(dāng)我把a(bǔ)lias的類型指定為any
時(shí),就不會(huì)報(bào)錯(cuò)了;
any類型 - 其他類型:
number
數(shù)字類型 ,boolean
布爾類型 ,void
類型
number
類型
var age: number = 13;
boolean
布爾類型
var man: boolean = true;
void
類型: 用于定義函數(shù)返回類型等
定義函數(shù)的返回類型為void
類型,當(dāng)函數(shù)有返回值時(shí),報(bào)錯(cuò)!,說明他不需要有任何類型的返回值.
- 自定義類型
自定義一個(gè)對(duì)象類型
class Person {
name: string;
age: number;
}
var zhangsan: Person = new Person();
zhangsan.name = 'jack';
zhangsan.age = 18;
參數(shù)新特性 之 默認(rèn)參數(shù)
在參數(shù)聲明后面用等號(hào)來指定參數(shù)的默認(rèn)值
1.只要在等號(hào)后邊賦上默認(rèn)值即可
var myname: string = "張三";
2.給方法的變量指定默認(rèn)值
- 給方法參數(shù)指定類型
function test(a:string, b:string, c:string) {
console.log(a);
console.log(b);
console.log(c);
}
test("xxx","yyy","zzz");
-
當(dāng)調(diào)用上面的方法,如果少傳一個(gè)參數(shù),就會(huì)報(bào)錯(cuò)
函數(shù)如果少傳一個(gè)參數(shù),就會(huì)報(bào)錯(cuò)
- 如何解決上面函數(shù)報(bào)錯(cuò)的問題呢? 可以給第三個(gè)參數(shù)指定一個(gè)默認(rèn)值; 這樣如果第三個(gè)參數(shù)不填,就會(huì)調(diào)用默認(rèn)值;
注意: 帶默認(rèn)值的參數(shù)一定要聲明在"最后面";
參數(shù)新特性 之可選參數(shù)
在方法的參數(shù)聲明后面用問號(hào)來標(biāo)明此參數(shù)為可選參數(shù)
以上面的方法為例,在b
參數(shù)后面寫上?
,定義為可選參數(shù);
function test(a: string, b?: string, c: string = "jack") {
console.log(a);
console.log(b);
console.log(c);
}
test("xxx");
注意:必選的參數(shù),不能在可選參數(shù)的后面
函數(shù)新特性
-
Rest and Spread
操作符: ①.用來聲明任意數(shù)量的方法參數(shù)
function func1(...args) {
args.forEach(function (arg) {
console.log(arg);
})
}
func1(1, 2, 3); // 1, 2, 3
func1(5, 6, 7, 8, 9); // 5, 6, 7, 8, 9
②.Rest and Spread
操作符:另外一個(gè)作用:展開運(yùn)算符
當(dāng)然此語法TypeScript
還不支持,會(huì)報(bào)錯(cuò),但是轉(zhuǎn)成js語法后可正常編譯.
function func1(a, b, c) {
console.log(a);
console.log(b);
console.log(c);
}
var args = [1, 2];
func1(...args); //執(zhí)行結(jié)果: 1, 2, undefined
var args2 = [7, 8, 9, 10, 11];
func1(...args2); //執(zhí)行結(jié)果: 7 , 8, 9
上述代碼編譯成js語法后
function func1(a, b, c) {
console.log(a);
console.log(b);
console.log(c);
}
var args = [1, 2];
func1.apply(void 0, args);
var args2 = [7, 8, 9, 10, 11];
func1.apply(void 0, args2);
-
generator
函數(shù):控制函數(shù)的執(zhí)行過程, 手工暫停和恢復(fù)代碼執(zhí)行;
類似于斷點(diǎn)調(diào)試(目前ts
還不支持,它是ES6
的一部分)
在babel
編輯器中
通過*號(hào)function* xxx()
聲明 generator
函數(shù)
function* doSomething(){
console.log("start");
yield; // 類似于一個(gè)斷點(diǎn)
console.log("finish");
}
var func1 = doSomething();
func1.next(); // 代表函數(shù)執(zhí)行,第一次走,函數(shù)會(huì)停在yield斷點(diǎn)處;
func1.next();// 第二次走,會(huì)越過yield斷點(diǎn)繼續(xù)往下執(zhí)行;
又例如:下面的函數(shù),當(dāng)價(jià)格小于limitPrice
時(shí),購買股票(點(diǎn)擊查看源碼)
function* getStockPrice(stock){
while(true){
yield Math.random()*100;
}
}
var priceGenerator = getStockPrice("IBM");
var limitPrice = 15;
var price = 100;
while(price > limitPrice){
price = priceGenerator.next().value;
console.log(`the generator return ${price}`);
}
console.log(`buying at ${price}`);
3.destructuring
析構(gòu)表達(dá)式:通過表達(dá)式,將對(duì)象或者數(shù)組拆解成任意數(shù)量的變量
也就是之前了解的"結(jié)構(gòu)賦值"
①:對(duì)象中的使用
function getStock() {
return {
code: "IBM",
price: 100
}
}
// ES5
var stock = getStock();
var code = stock.code;
var price = stock.price;
// ES6
// var { code, price } = getStock();
// 也可以設(shè)置別名
var { code: codex, price } = getStock();
// 調(diào)用別名
console.log(codex); // IBM
對(duì)象中多層嵌套屬性
function getStock() {
return {
code: "IBM",
price: {
price1: 200,
price2:400
},
aaa: "xixi",
bbb: "hahah"
}
}
// code: codex 設(shè)置別名
var { code: codex, price: { price1, price2 } } = getStock();
// 調(diào)用別名
console.log(codex); // IBM
console.log(price1); // 200
②. 數(shù)組中析構(gòu)表達(dá)式的使用
var array1 = [1, 2, 3, 4];
var [number1, number2] = array1;
console.log(number1); // 1
console.log(number2); // 2
取數(shù)組中的后兩個(gè)值
var array1 = [1, 2, 3, 4];
var [, , number1, number2] = array1;
console.log(number1); // 3
console.log(number2); // 4
舉一反三
var array1 = [1, 2, 3, 4];
var [number1, , , number2] = array1;
console.log(number1); // 1
console.log(number2); // 4
析構(gòu)表達(dá)式和Rest and Spread
操作符共同使用
var array1 = [1, 2, 3, 4];
var [number1, number2, ...others] = array1;
console.log(number1); // 1
console.log(number2); // 2
console.log(others); // 數(shù)組 [3, 4]
函數(shù)中的使用
var array1 = [1, 2, 3, 4];
function doSomething([number1, number2, ...others]) {
console.log(number1); // 1
console.log(number2); // 2
console.log(others); // 數(shù)組 [3, 4]
}
doSomething(array1);
表達(dá)式和循環(huán)
1.箭頭表達(dá)式:用來聲明匿名函數(shù),消除傳統(tǒng)匿名函數(shù)的this指針問題
-
簡單使用
//1.1 => 箭頭后面如果只有一行,不用寫大括號(hào)的 arg1 + arg2;
var sum1 = (arg1, arg2) => arg1 + arg2;
//1.2 如果是多行
var sum2 = (arg1, arg2) => {
return arg1 + arg2;
}
//1.3 沒有參數(shù)的箭頭函數(shù)
var sum3 = () => {
}
//1.4 只有一個(gè)參數(shù)的箭頭函數(shù),參數(shù)可以省略()
var sum4 = arg1 => {
console.log(arg1);
}
// 1.5 箭頭函數(shù)的簡單使用
var myArray = [1, 2, 3, 4];
// 篩選出數(shù)組中的偶數(shù)
console.log(myArray.filter(value => value % 2 == 0)); // 數(shù)組[2, 4]
-
消除傳統(tǒng)匿名函數(shù)的this指針問題
function getStock(name: string) {
this.name = name;
setInterval(function () {
console.log(`name is ${this.name}`); //打印結(jié)果: name is ,this.name的值為空
},1000);
}
var stock = new getStock("IBM");
function getStock2(name: string) {
this.name = name;
setInterval(() => {
console.log(`name is ${this.name}`); //打印結(jié)果:name is IBM,這下this.name就有值了,這樣更符合開發(fā)者的編程習(xí)慣
}, 1000);
}
var stock2 = new getStock2("IBM");
- 循環(huán)
forEach()
,for in
和for of
,還有find()
forEach()
var myArray = [1, 2, 3, 4];
myArray.desc = "four number"; // 給數(shù)組添加屬性,ts語法不支持
//注意:
//1.1 forEach()循環(huán)會(huì)去循環(huán)數(shù)組里面的元素,把屬性忽略掉
//1.2 forEach()循環(huán)中間不能break(跳出循環(huán))
myArray.forEach(value => console.log(value)); // 依次輸出1,2,3,4
for in
var myArray = ["jack", "lucy", "lily", "tom"];
myArray.desc = "four people"; // 給數(shù)組添加屬性,ts語法不支持
for (var n in myArray) {
// 注意 for in 循環(huán)的是集合的鍵,在此處指的是數(shù)組的下標(biāo)
console.log(n); // 0, 1, 2, 3, desc
// 要想打印出數(shù)組的值
console.log(myArray[n]);// jack, lucy, lily, tom, desc
}
// 注意:for in 循環(huán)可以把數(shù)組的屬性循環(huán)出來,這個(gè)行為很可能不是我們希望的行為
for of
var myArray = ["jack", "lucy", "lily", "tom"];
myArray.desc = "four people"; // 給數(shù)組添加屬性,ts語法不支持
for (var name of myArray) {
console.log(name); // jack, lucy, lily, tom
}
// for of 和 for in的區(qū)別:for of可以忽略掉數(shù)組的屬性,for of循環(huán)的是集合的值, for in 循環(huán)的是鍵
for of
循環(huán)是可以被打斷的
var myArray = ["jack", "lucy", "lily", "tom"];
myArray.desc = "four people"; // 給數(shù)組添加屬性,ts語法不支持
for (var name of myArray) {
if (name == "lily") break;// 當(dāng)循環(huán)到name==lily時(shí),跳出循環(huán)
console.log(name); // jack, Lucy
}
for of
循環(huán)字符串
var myaddress = "Shanghai";
for (var char of myaddress) {
console.log(char); // 打印結(jié)果: s ,h,a,,n,g,h,a,i
}
for of
還可以循環(huán)對(duì)象,map
等
find()
函數(shù),通過條件查詢出符合條件的
getStock(id: number): Stock {
return this.stocks.find(stock => stock.id === id);
}
TypeScript類
- 類 (class)
類是TypeScript
的核心,使用Typescript
開始時(shí),大部分代碼都是寫在類里面的.
-
類的定義
class Person{
name;
eat() {
console.log("i'm eatting");
}
}
// 類的實(shí)例化
var p1 = new Person();
p1.name = "batman";
p1.eat();
var p2 = new Person();
p2.name = "superman";
p2.eat();
// 一個(gè)類可以new出多個(gè)示例,他們擁有相同的屬性和方法,但是屬性的狀態(tài)不同!
類的訪問控制符: public
, private
, protected
public
: 默認(rèn)是訪問控制符,public的屬性和方法都是可以在類的內(nèi)部和外部訪問到的.
private
: 私有的,只可以在類的內(nèi)部被訪問到,在類的外部是訪問不到的!
protected
: 受保護(hù)的,受保護(hù)的屬性和方法可以在類的內(nèi)部和他的子類(繼承)里邊被訪問到.
-
類的構(gòu)造函數(shù)
constructor
:在類被實(shí)例化的時(shí)候調(diào)用,而且只會(huì)被調(diào)用一次,在外部是訪問不到的!
例如:類的實(shí)例化時(shí),必須傳進(jìn)來一個(gè)名字
class Person{
name;
constructor(name:string) {
this.name = name;
}
eat() {
console.log(this.name);
}
}
// 類的實(shí)例化
var p1 = new Person("batman");
p1.eat(); // batman
var p2 = new Person("superman");
p2.eat(); // superman
上面的方法等同于下面
class Person{
//public name:string 等同于生命了一個(gè)name屬性
constructor(public name:string) {
}
eat() {
console.log(this.name);
}
}
// 類的實(shí)例化
var p1 = new Person("batman");
p1.eat(); // batman
var p2 = new Person("superman");
p2.eat(); // superman
- 類的繼承
- extends:用來聲明一種繼承關(guān)系.
class Person{ constructor(public name:string) { } eat() { console.log(this.name); } } // Employee繼承自Person,Employee類可以獲得Person類的所有的屬性和方法 class Employee extends Person{ // 可以指定新的屬性和方法 code: string; work() { } } // el 同時(shí)擁有Person和Employee的屬性方法 var el = new Employee("meimei"); el.eat(); el.code = "123"; el.work();
- super
調(diào)父類的構(gòu)造函數(shù)
- extends:用來聲明一種繼承關(guān)系.
class Person{
constructor(public name:string) {
console.log("哈哈");
}
eat() {
console.log("I'm eatting");
}
}
class Employee extends Person{
constructor(name:string, code:string) {
super(name);// 調(diào)用父類的構(gòu)造函數(shù)
this.code = code;
console.log("嘻嘻");
}
// 可以指定新的屬性和方法
code: string;
work() {
// 在方法里面調(diào)用父類的方法
super.eat();
//調(diào)用自己方法
this.dowork();
}
dowork() {
console.log("I'm working");
}
}
// el 同時(shí)擁有Person和Employee的屬性方法
var el = new Employee("meimei","123");
el.work();
面向?qū)ο?之 泛型
泛型 (generic
): 參數(shù)化的類型,一般用來限制集合的內(nèi)容.
比如:下面的例子,尖括號(hào)里面的Person
就是泛型,他約定這個(gè)數(shù)組里面只能放Person
類型的數(shù)據(jù);
var workers: Array<Person> = [];
泛型的具體使用:
class Person{
constructor(public name:string) {
console.log("哈哈");
}
eat() {
console.log("I'm eatting");
}
}
class Employee extends Person{
constructor(name:string, code:string) {
super(name);// 調(diào)用父類的構(gòu)造函數(shù)
this.code = code;
console.log("嘻嘻");
}
// 可以指定新的屬性和方法
code: string;
work() {
// 在方法里面調(diào)用父類的方法
super.eat();
//調(diào)用自己方法
this.dowork();
}
dowork() {
console.log("I'm working");
}
}
/**********************泛型的具體使用***********************/
var workers: Array<Person> = []; //指定了 workers類型為數(shù)組,且數(shù)組只能放Person類型的數(shù)據(jù)
workers[0] = new Person("zhangsan");
workers[1] = new Employee("lisi", "2"); // Employee是繼承自Person,也可以放
workers[2] = 2;// 就會(huì)報(bào)紅色警告
面向?qū)ο?之 接口(Interface)
接口(Interface):用來建立某種代碼約定,使得其他開發(fā)者在調(diào)用某個(gè)方法或者創(chuàng)建新的類時(shí),必須遵循接口所定義的代碼約定;(js中沒有,只有ts
中有)
- Interface 聲明屬性
// 聲明接口
interface IPerson{
name: string;
age: number;
}
//聲明一個(gè)類
class Person{
// 作用: 參數(shù)方法類型聲明
// config: IPerson >>> IPerson類型的參數(shù)
constructor(public config: IPerson) {
}
}
// 實(shí)例化時(shí),必須要傳一個(gè)IPerson類型的對(duì)象進(jìn)去
// 注意:多傳一個(gè)屬性和多傳一個(gè)屬性都會(huì)報(bào)錯(cuò)
var p1 = new Person({
name: "zhangsan",
age: 18
});
- Interface 聲明方法
implements 實(shí)現(xiàn)的意思
// 聲明一個(gè)方法
interface Animal {
eat();
}
// implements 作用:聲明 Sheep 這個(gè)類實(shí)現(xiàn) Animal 的接口
// 它必須實(shí)現(xiàn) Animal 的eat()方法
class Sheep implements Animal{
eat() {
console.log("I eat grass");
};
}
class Tiger implements Animal{
eat() {
console.log("I eat meat");
};
}
面向?qū)ο?之 模塊
模塊(Module):模塊可以幫助開發(fā)者將代碼分割為可重用的單元.開發(fā)者可以自己決定將模塊中的哪些資源(類,方法,變量)暴露出去供外部使用,哪些資源只在模塊內(nèi)使用.
在a.ts
中暴露一些屬性,方法和類
// 有兩個(gè)關(guān)鍵字支撐模塊的特性: export import
// 對(duì)外暴露一些東西
export var prop1;
// 不對(duì)外暴露
var prop2;
// 對(duì)外暴露一個(gè)方法
export function func1() {
}
// 不對(duì)外暴露方法
function func2() {
}
// 對(duì)外暴露一個(gè)類
export class Class1 {
}
// 不對(duì)外暴露一個(gè)類
class Class2 {
}
在b.ts
中引用a的屬性,方法和類
// 一個(gè)模塊 既可以對(duì)外暴露(export)它的屬性、方法和類,也可以import別人的屬性、方法和類;
import {Class1, func1, prop1} from "./a";
console.log(prop1);
func1();
new Class1();
export function func3(){
}
面向?qū)ο?之 注解
注解(annotation): 注解為程序的元素(類, 方法, 變量)加上更直觀更明了的說明, 這些說明信息與程序的業(yè)務(wù)邏輯無關(guān),而是供指定的工具或框架使用的;
面向?qū)ο?之 類型定義文件(*.d.ts)