TypeScript入門

一、es5、es6、TypeScript、JavaScript的區別和聯繫
es是客戶端腳本語言的規範,es5,es6是不同的版本。javascript跟typescript是不同的腳本語言,javascript 實現了es5規範,typescript實現了es6規範。typescript慢慢的將JavaScript由一門弱語言變強,允許爲變量指定類型,變得更加嚴謹

二、基礎用法
1、編譯器
(1)安裝ts本地編譯器

>sudo npm install -g typescript
>tsc --version #檢查是否安裝完成

這個編譯器的作用是將typescript 代碼轉成JavaScript代碼。因爲ES6規範是在2015年後發佈的,而現在大部分用戶的瀏覽器支持ES5規範,所以需要將typescript代碼轉換成JavaScript代碼纔可以在用戶的瀏覽器中運行

(2)IDE下自動編譯
打開webstorm,新建ts文件,編輯文件會出現提示Compile Ts to Js? OK即可

2、ts字符串特性
(1)字符串模板 ${xxx}
(2)多行字符串 “
(3)自動拆分字符串
eg:

var myname = "an hai jun";
var getName = function(){
  return "an hai jun";
}
console.log(`<div>
  <span>${myname}</span>
  <span>${getName()}</span>
  <div>xxx</div>
  </div>
`)

function test(template,name,age){
    console.log(template);
    console.log(name);
    console.log(age);
}
var myname="zs";
var getAge=function(){
    return 18
}
//用一個字符串模板去調用方法,方法會自動拆分字符串,第一個參數爲整個字符串的切割,之後的參數是模板中的變量,按順序依次排列。
test`hello my name is ${myname},i'm ${getAge()}`

3、ts參數類型
(1)變量類型

var myname : string = "字符串類型"; //在下文賦值時,自動檢測類型,不符則提示錯誤
var alias : any = "賦任何類型的值"
var age : number = 13;
var man : boolean = true;

(2)方法類型,不需要任何返回值void

function test(name : string) : void {
  //會提示錯誤
  return "";
}
test(13)    //會提示錯誤

(3)自定義類型

class Person {
  name: string;
  age: number;
}

var zhangsan : Person = new Person();
zhangsan.name = "zhangsan";
zhangsan.age = "13";

(4)參數默認值

var myname:string="test"
function test(a:string,b:string,c:string="test"){
//c可以不傳,a,b必須傳
}

(5)可選參數,參數後加?

function test(a: string, b?: string, c: string="test"){}
test("xxx");

4、函數新特性
(1)Rest and Spread操作符 …

function fun1(...args){
    args.forEach(function(arg){
      console.log(arg)
    })
}
fun1(1,2,3,4)

反過來,ES6支持,ts暫不支持

function func1(a,b,c){
    console.log(a);
    console.log(b);
    console.log(c);
}
var args = [1,2]
func1(...args);//輸出 1 2 undefined
var args2=[7,8,9,10,11];
func1(...args2);//輸出 7 8 9

(2)generator函數
函數新特性之generator函數:控制函數的執行過程,手工暫停和恢復代碼執行
聲明方法,在function後面另*號,

function* countAppleSales () {
  var saleList = [3, 7, 5];
  for (var i = 0; i < saleList.length; i++) {
    yield saleList[i];
  }
}
var appleStore = countAppleSales(); // Generator { }
console.log(appleStore.next()); // { value: 3, done: false }
console.log(appleStore.next()); // { value: 7, done: false }
console.log(appleStore.next()); // { value: 5, done: false }
console.log(appleStore.next()); // { value: undefined, done: true }
//需要把方法聲明成一個方法,然後再使用變量的next()方法;
//yield用來暫停,調用函數的next方法,方法纔會繼續執行;
//value是yield後面表達式的值,done代表函數有沒有完全執行完成

(3)析構表達式

①通過表達式將對象或數組拆解成任意數量的變量
eg:

function getStock(){
    return{
        code:"IBM",
        price:100
    }
}
var {code,price} = getStock();
//等同於
var stock = getStock();
var code = stock.code;
var price = stock.price;

變量名要一樣,如果非要用別的名稱可以使用:{code:codex,price}取別名的方式
如果對象中的屬性又是一個對象,例如:

function getStock(){
    return{
        code:"IBM",
        price:{
            price1:200,
            price2:400
        }
    }
}

這時候,{code,price}中,price取到的就是一個對象,包含price1:200,price2:400,如果非要取其中的一個值的話,可以再使用一個析構表達式:{code,price:{price2}}就可以以取出price2的值了。如果getStock中還有其他屬性,是不影響這個取值的。

②從數組中取值到本地變量

var arr1 = [1,2,3,4];
var [number1,number2] = array1;
//與對象的析構不同的是,數組是用[]來括起來,對象是用{}括出來,如果要拿第3個和第4個話, 這樣使用[,,number1,number2]
//還有一個使用方式[number1,number2,...others]表示數組中第1和第2個元素分別放到number1和number2中,剩下的,以數組的方式放到others變量中去。

//析構表達式作爲方法的參數:
var arr1 = [1,2,3,4];
function doSomething([number1,number2,...others]){
console.log(number1);
console.log(number2);
console.log(number3);}
doSomething(array1);

5、表達式與循環
(1)箭頭表達式

//一行表達式
var sum = (arg1,arg2) => arg1 + arg2

//多行表達式,效果和以上寫法等同
var sum = (arg1,arg2) => {
    return arg1 + arg2
}

//無參數
var sum = () => {
}

//一個參數
var sum = arg1 => {
    console.log(arg1)
}

//綜合例子
var myArray=[1,2,3,4,5];
console.log(myArray.filter(value=>value%2==0));

//消除傳統匿名函數的this指針問題例子
function getStock(name:string){
    this.name = name;
    setInterval(function () {
        console.log("name is:" + this.name)
    },1000);
}
var stock = new getStock("IBM")  //打印不出this.name

function getStock2(name:string){
    this.name = name;
    setInterval(()=>{
        console.log("name is:" + this.name)
    },1000);
}
var stock=new getStock2("IBM") //可以正常打印出this.name

(2)for of循環

①forEach

var myArray=[1,2,3,4];
myArray.desc='four number';
myArray.forEach(value=>console.log(value))//1,2,3,4  特點:忽略屬性值,不能直接break;跳出循環

②for in

for(var n in myArray){
    console.log(n)          //0,1,2,3,desc
    console.log(myArray[n])     //1,2,3,4,'four number'
}

③for of

for(var n of myArray){
    console.log(n)          
    //1,2,3,4 特點:忽略屬性值,能直接break;跳出循環
}
//for of循環字符串
for(var n of 'four number'){
    console.log(n)          //字符串中每個字符打印出來
}

6、面向對象特性
(1)類
①類的聲明和訪問

class Person { 
    public aaa;//訪問控制符public:默認,在類內外部可以訪問
    private bbb = 'b';//訪問控制符private:只能在類內部可以訪問
    protected ccc='cc';//訪問控制符protected:在類內部和類的子類中可以訪問
    eat() { 
    console.log(this.aaa+this.bbb)
    }
}
var p1 = new Person();
p1.aaa = 'a';
p1.eat();

②構造函數

class Person { 
    constructor(public name:string) {                               
    }
    //等同於:
    //name
    //constructor(name:string) {        
    //this.name=name;                   
    //}

    eat() { 
        console.log(this.name)
    }
}
var p1 = new Person('hhh');
p1.eat();

③類的繼承

class Person { 
    constructor(public name:string) {                               
    }   
    eat() { 
        console.log(this.name)
    }
}
class Employee extends Person{ 
    constructor(name:string,public code:string) {        
        super(name)
    }
    work() { 
        super.eat();
        this.doWork();
    }
    private doWork() { 
        console.log(this.code)
    }
}
var e1 = new Employee("name",'13');
e1.work();
/*用extends關鍵字申明繼承關係,繼承父類的全部屬性和方法。
子類在聲明constructor方法時一定要加super關鍵字,參數爲父類構造函數必須要傳的參數,如無則不傳。另外子類可以通過super調用父類定義的方法。*/

(2)泛型
參數化的類型,一般用來限制集合的內容
例子:

class Person { 
    public name;
    eat() { 
        console.log(this.name)
    }
}
class Employee extends Person{ 
    constructor(name:string,public code:string) {        
        super()
    }
    work() { 
        super.eat();
        this.doWork();
    }
    private doWork() { 
        console.log('www')
        console.log(this.code)
    }
}
var work: Array<Person> = [];       //申明work這個數字包含的數據只能是Person類型的
work[0] = new Person()
work[1] = new Employee('jimmy', '13')   //子類也屬於父類,不會報錯
work[2]=1               //1不屬於Person類型,會報錯

(3)接口
接口:用來建立某種代碼約定,使得其它開發者在調用某個方法或創建新的類時必須遵循接口所定義的代碼約定。

//第一種用法:
interface IPerson{
  name;string;
  age:number;
}

class Person{
  constructor(public config:IPerson){
  }
}
var p1=new Person({name:"zhangsan",age:18});//必須符合接口的格式,爲接口中的屬性賦值

//第二種用法:
interface Animal{
  eat();
}
class Sheep implements Animal{       //implements關鍵字代表該類實現該接口,該類必須定義接口中的方法
  eat(){
    console.log("i eat grass");
  }
}
class Tiger implements Animal{
  eat(){
    console.log("i eat feet");
  }
}

(4)模塊
模塊可以幫助開發者將代碼分割爲可重用的單元。開發者可以自己決定模塊中哪些資源(類、方法、變量)暴露出去供外部使用,哪些資源只在模塊內使用。ts裏一個文件就是一個模塊。
export : 導出,對外暴露
import : 導入,引入外部資源

//eg:
//a.ts
export var prop1;
var prop2;
export function func1(){
}
function func2(){
}
export class Clazz1(){
}
class Clazz2(){
}
//b.ts
import {prop1,func1,Clazz1} from "./a";
console.log(prop1)
func1();
new Clazz1();

(5)註解annotation
註解爲程序的元素(類,方法、變量)加上更直觀明瞭的說明,這些說明信息與程序的業務邏輯無關,而是供指定的工具或框架使用的。這一塊並沒有太理解,先留白

(6)類型定義文件(*.d.ts)
類型定義文件用來幫助開發者在TypeScript中使用已有的JavaScript的工具包

①類型定義文件是爲了能在TS上使用JS代碼庫、框架而引入的以.d.ts結尾的文件。

②類型定義文件是別人配好的:https://github.com/DefinitelyTyped/DefinitelyTyped
比如使用jq :https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/jquery/index.d.ts

③可以使用專門用來安裝類型定義文件的工具:https://github.com/typings/typings

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章