1. 程式人生 > >TypeScript學習筆記之函式

TypeScript學習筆記之函式

函式
函式是一組可以隨時隨地執行的語句。是 ECMAScript 的核心。和JavaScript一樣,TypeScript函式可以建立有名字的函式和匿名函式。
javascript中的函式:

/*普通函式*/
function add(x, y) {
    console.log(x + y);
}
add(1, 2);
/*匿名函式*/
var addFun = function (x, y) {
    console.log(x + y);
};
addFun(2, 3);

在TypeScript中,我們可以給函式指定型別,這樣在編譯階段會規避很多錯誤.函式型別分為引數型別和返回值型別,如下程式碼所示,引數型別直接在引數後指定,返回值型別則在該函式後面指定。 TypeScript能夠根據返回語句自動推斷出返回值型別,因此我們通常省略它。


/*普通函式*/
function add(x:number,y:number):number{
    return x+y;
}
add(1,2);
/*匿名函式*/
var addFun=function (x:number,y:number):number {
    return x+y;
}

addFun(2,3);

完整函式型別
在TypeScript中,為了提高程式碼的可讀性,提供給我們另一種寫法,這種寫法會明確的指出引數的意義。
如下程式碼所示,我們很容易就明白這個方法傳的引數是數學分數和英語分數,該方法返回的是數學和英語分數的和。返回值型別是函式型別的必要部分,如果函式沒有返回任何值,你也必須指定返回值型別為 void而不能留空。

let myAdd:(mathScores:number,englishScores:number)=>number=function (x:number,y:number):number {
    return x+y;
}

推斷型別
如果你在賦值語句的一邊指定了型別但是另一邊沒有型別的話,TypeScript編譯器會自動識別出型別

let myAdd:(mathScores:number,englishScores:number)=>number=function (x:number,y:number) {
    return x+y;//這裡會推斷返回的是number型別的資料
}

可選引數
TypeScript裡的每個函式引數都是必須的。也就是說我們在函式中定義了幾個引數在呼叫的時候就要傳幾個引數。而在javaScript中,引數是可傳可不傳的,如果不傳,預設是undefined。 在TypeScript裡我們可以在引數名後加上 ?實現可選引數的功能。
如下圖程式碼所示,z是個可選引數,看列印結果可以看到,如果不傳,預設就是undefined。需要注意的是,可選引數必須跟在必須引數後面。也就是說,如果x是可選引數,那麼,x就要放到y的後面。

/*可選引數 可選引數用?表示 呼叫的時候可傳可不傳 不傳的話預設值是undefined 可選引數必須放到其他引數後面*/
function add1(x:string,y?:string):string{
    console.log(x+y);
    return x+y;
}
add1("888");//888undefined
add1("88","yzq");//yzq

預設引數
在TypeScript裡,我們也可以為引數提供一個預設值,當用戶沒有傳遞這個引數或傳遞的值是undefined時。 它們叫做有預設初始化值的引數。與可選引數不同的是,預設引數不是一定要放到最後的,但是如果預設引數放到了普通引數的前面,恰好我們不想給預設引數傳其它值的話,則必須傳入 undefined值來獲得預設值。

/*預設引數 預設引數和可選引數類似  呼叫的時候可傳可不傳 不傳的話是預設值  傳的話會覆蓋值 如果不想給預設引數指定值必須傳入undefined*/
function add2(x="hello",y:string,z?:string){
    console.log(`${x}--${y}--${z}`);
}
add2(undefined,"yzq");//hello--yzq--undefined
add2("hi","yzq");//hi--yzq--undefined
add2("hi","yzq","hahaha");//hi--yzq--hahaha

剩餘引數
必要引數,可選引數和預設引數都代表一個引數,有時候我們並不知道到底有多少個引數傳進來,這個時候我們就可用剩餘引數了。我們可以傳多個,也可以什麼都不傳。

/*剩餘引數(可變引數)*/
function add3(...name:string[]){
    console.log(name.join(","));
}
add3();//什麼都不傳返回空
add3("1","2","3");//1,2,3

this關鍵字和Lambda表示式
this是Javascript語言的一個關鍵字。在 Java 等面向物件的語言中,this 關鍵字的含義是明確且具體的,即指代當前物件。一般在編譯期確定下來,或稱為編譯期繫結。而在 JavaScript 中,this 是動態繫結,或稱為執行期繫結的,這就導致 JavaScript 中的 this 關鍵字有能力具備多重含義。關於this的詳解請看:javascript中this關鍵的詳解

/**
/**
 * Created by yzq on 2017/1/11.
 */
var say = {
    name: "yzq",
    age: 23,
    hello: function () {
        return function () {
            return this.name;
        };
    },
    hi: function () {
        return this.name;

    }
}
var h=say.hello();//這裡返回了一個方法
console.log(h()) ;//這裡呼叫的話相當於window.h();獲取不到say物件裡的name。此時,該函式裡的this指向的是全域性物件window.
console.log(say.hi());//這裡呼叫的話,hi方法裡面的this指向的是say這個物件,因此,會列印yzq

Lambda表示式
也叫箭頭函式,就是用來宣告匿名函式,並且能消除傳統的javascript中匿名函式this指標問題。

/**
 * Created by yzq on 2017/1/11.
 */

/*簡單的箭頭函式 無引數且無返回值*/
var add = () => {console.log("無引數且無返回值")};

/*有一個引數 且有返回值*/
var add1=x=>`有一個引數的時候可以不寫(),${x}
 ass`;

/*多個引數*/
var add2=(x,y,z)=>{
    console.log(x+y+z);
}
add2(1,2,3);

編譯成js程式碼後

/**
 * Created by yzq on 2017/1/11.
 */
/*簡單的箭頭函式 無引數且無返回值*/
var add = function () { console.log("無引數且無返回值"); };
/*有一個引數 且有返回值*/
var add1 = function (x) { return ("\u6709\u4E00\u4E2A\u53C2\u6570\u7684\u65F6\u5019\u53EF\u4EE5\u4E0D\u5199()\uFF0C" + x + "\n ass"); };
/*多個引數*/
var add2 = function (x, y, z) {
    console.log(x + y + z);
};
add2(1, 2, 3);

應用場景
TypeScript中

/*簡單用法 將一個數據中的能被2整除的值過濾出來*/
let numArr:Array<number>=[1,2,3,4,5,6,7];
console.log(numArr.filter(value=>value%2==0));

編譯成js後

/*簡單用法 將一個數據中的能被2整除的值過濾出來*/
var numArr = [1, 2, 3, 4, 5, 6, 7];
console.log(numArr.filter(function (value) {
    return value % 2 == 0;
}));

下面我們來看看之前那個this關鍵字的問題,我們可以使用Lambda表示式來消除這個問題。如下程式碼所示,我們只需要將匿名函式用Lanmbda表示式的方式來寫,Lambad表示式會自動將this引用繫結到當前物件,這也是Lambad表示式最有價值的地方。

var say = {
    name: "yzq",
    age: 23,
    hello: function () {
        return ()=> {
            return this.name;
        };
    },
    hi: function () {
        return this.name;

    }
}
var h=say.hello();//這裡返回了一個方法
console.log(h()) ;//列印yzq
console.log(say.hi());//列印yzq

過載
TypeScript中的過載和java的過載就完全不一樣了。在java中,允許一個類中有多個同名不同參的方法,這些方法就叫做過載,java會根據傳入的引數去呼叫相應的過載方法。
在javaScript中是沒有過載的概念的,個人認為在TypeScript中方法過載存在的主要意義在於智慧提示,方便呼叫者在呼叫方法的時候知道該傳什麼引數。 TypeScript 是會檢查引數個數、型別是否匹配,然後去呼叫過載方法,以避免出現呼叫錯誤。

/**
 * Created by yzq on 2017/1/11.
 */
/*過載*/

function add(x:number,y:number):number;

function add(x:string):string;

function add(x):any{
    if (typeof x=="number"){
        console.log(`數字`)
    }else {
        console.log(`字串`)
    }
}
add(1,2);