gitHub:http://www.liu12fei08fei.top/blog/10typescript.htmlhtml
課程內容介紹前端
課程介紹-前置知識git
TypeScript的優點es6
搭建TypeScript開發環境web
什麼是compiler?爲何須要compiler?typescript
搭建本地TypeScript開發環境數組
TypeScript-字符串新特性(全部例子都是es6語法)瀏覽器
1、 多行字符串框架
var str = `111,
222,
333,
444`;
2、 字符串模板:在多行字符串裏,用一個表達式去插入變量或者用以調用方法
var myName = '怪誕咖啡';
var getName = function () {
return myName;
}
console.log(`Hello ${myName}`); // 調用變量
console.log(`Hello ${getName()}`); // 調用函數
3、 自動拆分字符串:當用一個字符串模板去調用一個方法的時候,這個字符串模板裏面表達式的值會自動賦值給被調用方法中的參數
function test(name, age, job) {
console.log(name);
console.log(age);
console.log(job);
}
var myName = "怪誕咖啡";
var getAge = function () {
return 18;
}
test`Hello my name is ${myName}, I'm ${getAge()}`;
TypeScript-參數新特性
參數類型
1、 在參數名稱後面使用冒號來指定參數的類型
var myName: string = '怪誕咖啡';
myName = 13;
2、 類型推斷機制,就是當第一次給變量賦值,此變量的類型就固定爲第一次賦值的類型
var myName = '怪誕咖啡';
myName = 13;
3、 要想在typescript環境下任意賦值,就須要賦值爲:any
var myName:any = '怪誕咖啡';
myName = 13;
4、 其餘基本類型
void類型例子:
function test(): void{
return ''; // 報錯
}
function test(): string{
return ''; // 不報錯
}
5、 除了給變量和函數聲明類型外,還能夠給參數聲明類型
function test(name: string, age) {
return name;
}
test(1); // 報錯,只能使用string類型進行調用
注:介紹瞭如何聲明類型、typescript類型推斷機制、五種基本的類型、能夠聲明類型的位置
6、 自定義類型:在typescript裏面,能夠經過class或接口來申明自定義類型
class Person{
name: string;
age: number;
}
var feifei: Person = new Person();
feifei.name = '怪誕咖啡';
feifei.age = 18;
默認參數
在參數聲明後面用等號來指定參數的默認值
function test(a: string, b: string, c: string) {
console.log(a);
console.log(b);
console.log(c);
}
test('1','2','3'); // 必須傳遞三個string類型的參數,不然提示錯誤
給參數指定默認值以後,能夠不傳遞參數
function test(a: string, b: string, c: string='攻城獅') {
console.log(a);
console.log(b);
console.log(c);
}
test('1', '2'); // 只傳遞兩個參數,第三個參數使用默認值
可選參數
在方法的參數聲明後面用問號來標明此參數爲可選參數
function test(a: string, b?: string, c: string='攻城獅') {
console.log(a);
console.log(b);
console.log(c);
}
test('1'); // 只傳遞一個參數,第二個參數爲undefined,第三個參數爲默認值
注意幾點:
function test(a: string, b?: string, c: string='攻城獅') {
console.log(a);
console.log(b.length);
console.log(c);
}
說明:b參數爲可選參數,在不傳遞參數值的狀況下是不容許調用undefined的length屬性的
function test(a?: string, b: string, c: string='攻城獅') {
console.log(a);
console.log(b);
console.log(c);
}
說明:我給a設置爲可選參數,b爲必選參數,會直接報錯;和設置默認值是同樣的,不容許在必選參數前面設置默認值
函數新特性
Rest and Spread操做符(...):用來聲明任意數量的方法參數,即rest參數
function fun(...args) {
args.forEach(function (arg) {
console.log(arg);
});
}
fun(1, 2, 3);
console.log('******'); // 分隔符
fun(10,8,18,49,100,7)
一個Rest and Spread操做符,反方向使用的方法--目前版本2.6不支持
function fun(a, b, c) {
console.log(a);
console.log(b);
console.log(c);
}
var args = [1, 2];
fun(...args); // 在typescript中報錯,在轉化的es5中支持,返回值爲:1 2 undefined
console.log('*****');
var args2 = [7, 8, 9, 10, 12];
fun(...args2); // 在typescript中報錯,在轉化的es5中支持,返回值爲:7 8 9
generator函數:控制函數的執行過程,手工暫停和恢復代碼執行
聲明一個generator函數,只要在function後面添加一個便可:`function fun(){}`
function* fun(){
console.log('start');
yield;
console.log('finish');
}
// fun(); // 這樣調用generator是不起做用的,必須使用下面的方式調用
var fn = fun();
fn.next(); // 打印start
fn.next(); // 打印finish
destructuring析構表達式:經過表達式將對象或數組拆解成任意數量的變量
function a() {
return {
myName: '怪誕咖啡',
age: {
age1: 18,
age2:80
}
}
}
var { myName, age: { age1, age2 } } = a(); // 析構表達式,包括嵌套屬性
var { myName:newName, age: { age1, age2 } } = a(); // 析構表達式,給myName起一個新的名字newName
console.log(age1);
console.log(age2);
解析:返回值,即return返回值,的結構和咱們的析構表達式的結構{ myName, age: { age1, age2 } }一一對應,因此析構表達式,便可理解爲,解析結構得到對象屬性的方法
var arr = [1, 2, 3, 4];
var [num1, num2, ...other] = arr; // 獲取第一個和第二個,其他變量賦值給other
var [,,num3,num4] = arr; // 獲取第三和第四個值
析構表達式好處:當你須要從一個對象的屬性或者是數組的元素裏面,用其中的值賦值給其他變量的時候,可讓咱們寫更少的代碼
表達式和循環
箭頭表達式:用來聲明匿名函數,消除傳統匿名函數的this指針問題
// 無參數表達式
var sum = () => {}
// 只有一個參數的表達式
var sum = arg => {}
// 單行表達式
var sum = (arg1, arg2) => arg1 + arg2;
// 多行表達式
var sum2 = (arg1, arg2) => {
return arg1 + arg2;
}
實際例子:
var arr = [1, 2, 3, 4, 5];
var flt = arr.filter(val => val % 2 == 0);
console.log(flt);
箭頭函數的優點:
function fn(myName: string) {
this.myName = myName;
setInterval(function () {
console.log('myName is:'+this.myName);
},1000);
}
var myName = 1; // 全局myName,後面的this指向了全局,而不是a
var a = new fn('怪誕咖啡');
function fn(myName: string) {
this.myName = myName;
setInterval(() => {
console.log('myName is:'+this.myName);
},1000);
}
var myName = 1;
var a = new fn('怪誕咖啡'); // 消除指向問題
forEach()、for in和for of
forEach:
var arr = [1, 2, 3, 4];
arr.desc = 'I am number type!'; // 這行在typescript裏面會報錯
arr.forEach(val => console.log(val));
問題:
for in
var arr = [11, 22, 33, 44];
arr.desc = 'I am number type!';
for (var item in arr) {
console.log(item); // key=> 1,2,3,4,desc
console.log(arr[item]); //value=>11,22,33,44,I am number type!
}
問題:
for of
var arr = [11, 22, 33, 44];
arr.desc = 'I am number type!';
for (var item of arr) {
console.log(item); // key=> 11,22,33,44
}
面向對象特性
類(class):TypeScript的核心,使用TypeScript開發時,大部分代碼都是寫在類裏面的。
類的定義
class Person{
}
class Person{
name;
eat() {
console.log('I am eating!');
}
}
class Person{
name;
eat() {
console.log('I am eating!');
}
}
var p1 = new Person();
p1.name = 'Hello';
p1.eat();
var p2 = new Person();
p2.name = 'World';
p2.eat();
返回控制符
類的構造函數,即:constructor方法
class Person{
constructor() {
console.log('構造函數')
};
name='默認值';
eat() {
console.log('I am eating!');
}
}
var p1 = new Person();
p1.name = 'Hello';
p1.eat();
var p2 = new Person();
p2.name = 'World';
p2.eat();
構造函數的做用:能夠在實例化的時候,指定相應屬性
class Person{
constructor(public name:string) {
};
eat() {
console.log(this.name);
}
}
var p1 = new Person('Hello');
p1.eat();
var p2 = new Person('World');
p2.eat();
注意:構造函數裏面,定義屬性,要使用控制符來明確聲明,即:public name:any;若是是name:any這樣,說明沒有聲明該屬性,下面沒法訪問到
類的繼承:兩個關鍵字
extends,得到繼承類中全部屬性和方法
class Person{
constructor(public name:string) {
};
eat() {
console.log(this.name);
}
}
class Employee extends Person{
// 定義新的屬性和方法
code: string;
work() {
}
}
let em = new Employee('coffee');
em.eat();
super
調用父類的構造函數
class Person{
constructor(public name:string) {
console.log('父類構造函數');
};
eat() {
console.log(this.name);
}
}
class Employee extends Person{
constructor(name: string, code: string) {
// 必須調用父類的構造函數,這是硬性規定
super(name);
console.log('子類構造函數');
this.code = code;
};
code: string;
work() {
}
}
let em = new Employee('coffee','8');
em.eat();
用來調用父類的方法
class Person{
constructor(public name:string) {
console.log('父類構造函數');
};
eat() {
console.log(this.name);
}
}
class Employee extends Person{
constructor(name: string, code: string) {
// 必須調用父類的構造函數,這是硬性規定
super(name);
console.log('子類構造函數');
this.code = code;
};
code: string;
work() {
// 調用父類的方法
super.eat();
};
// 返回控制符
private doWork() {
}
}
let em = new Employee('coffee','8');
em.work();
面向對象特性
泛型-generic:是指參數化的類型,通常用來限制集合的內容
class Person{
constructor(public name:string) {
console.log('父類構造函數');
};
eat() {
console.log(this.name);
}
}
class Employee extends Person{
constructor(name: string, code: string) {
// 必須調用父類的構造函數,這是硬性規定
super(name);
console.log('子類構造函數');
this.code = code;
};
code: string;
work() {
// 調用父類的方法
super.eat();
};
private doWork() {
}
}
var workers: Array<Person> = [];
workers[0] = new Person('神經了');
workers[1] = new Employee('神經了', '8');
workers[2] = 3; // 報錯,指定放Person類型的數據
接口-Interface:用來創建某種代碼約定,使得其它開發者在調用某個方法或建立新的類時必須遵循接口所定義的代碼約定
interface IPerson{
name: string;
age: number;
}
class Person{
constructor(public config:IPerson){}
}
// 聲明屬性
var p1 = new Person({
name: 'coffee',
age:8
});
console.log(p1);
實現對應的接口中的方法:
interface Animal{
eat();
}
class Sheep implements Animal{
eat() {
console.log('I eat grass');
}
}
class Tiger implements Animal{
eat() {
console.log('I eat meat');
}
}
模塊-module:模塊能夠幫助開發者將代碼分割爲可重用的單元。開發者能夠本身決定將模塊中的哪些資源(類、方法、變量)暴露出去供外部使用,哪些資源只在模塊內使用。
// 文件a
import {newName} from "./b"; // 引入b文件,使用b文件中提供的接口newName
// a文件對外提供接口
export var prop1;
var prop2;
export function func1(){
}
function func2(){
}
export class Class1{
}
class Class2{
}
// 得到b文件提供的接口
console.log(newName);
// b文件
import {Class1, func1, prop1} from "./a"; // 引入a文件
// 獲取a文件提供的接口
console.log(prop1);
func1();
new Class1{
}
// 對外提供接口
export var newName;
註解-annotation:註解爲程序的元素(類、方法、變量)加上更直觀更明瞭的說明,這些說明信息與程序的業務邏輯無關,而是供指定的工具或框架使用的
類型定義文件(*.d.ts):類型定義文件用來幫助開發者在TypeScript中使用已有的JS的工具包;如:jQuery、zepto等
如何找到類型定義文件,確定不能本身一個個的寫;使用tyings來快速啓動