<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 函數的類型 > [函數是 JavaScript 中的一等公民](https://llh911001.gitbooks.io/mostly-adequate-guide-chinese/content/ch2.html) ## 函數聲明 在 JavaScript 中,有兩種常見的定義函數的方式——函數聲明(Function Declaration)和函數表達式(Function Expression): ```js // 函數聲明(Function Declaration) function sum(x, y) { return x + y; } // 函數表達式(Function Expression) let mySum = function (x, y) { return x + y; }; ``` 一個函數有輸入和輸出,要在 TypeScript 中對其進行約束,需要把輸入和輸出都考慮到,其中函數聲明的類型定義較簡單: ```ts function sum(x: number, y: number): number { return x + y; } ``` 注意,**輸入多余的(或者少于要求的)參數,是不被允許的**: ```ts function sum(x: number, y: number): number { return x + y; } sum(1, 2, 3); // index.ts(4,1): error TS2346: Supplied parameters do not match any signature of call target. ``` ```ts function sum(x: number, y: number): number { return x + y; } sum(1); // index.ts(4,1): error TS2346: Supplied parameters do not match any signature of call target. ``` ## 函數表達式 如果要我們現在寫一個對函數表達式(Function Expression)的定義,可能會寫成這樣: ```ts let mySum = function (x: number, y: number): number { return x + y; }; ``` 這是可以通過編譯的,不過事實上,上面的代碼只對等號右側的匿名函數進行了類型定義,而等號左邊的 `mySum`,是通過賦值操作進行類型推論而推斷出來的。如果需要我們手動給 `mySum` 添加類型,則應該是這樣: ```ts let mySum: (x: number, y: number) => number = function (x: number, y: number): number { return x + y; }; ``` 注意不要混淆了 TypeScript 中的 `=>` 和 ES6 中的 `=>`。 在 TypeScript 的類型定義中,`=>` 用來表示函數的定義,左邊是輸入類型,需要用括號括起來,右邊是輸出類型。 在 ES6 中,`=>` 叫做箭頭函數,應用十分廣泛,可以參考 [ES6 中的箭頭函數][]。 ## 用接口定義函數的形狀 我們也可以使用接口的方式來定義一個函數需要符合的形狀: ```ts interface SearchFunc { (source: string, subString: string): boolean; } let mySearch: SearchFunc; mySearch = function(source: string, subString: string) { return source.search(subString) !== -1; } ``` 采用函數表達式|接口定義函數的方式時,對等號左側進行類型限制,可以保證以后對函數名賦值時保證參數個數、參數類型、返回值類型不變。 ## 可選參數 前面提到,輸入多余的(或者少于要求的)參數,是不允許的。那么如何定義可選的參數呢? 與接口中的可選屬性類似,我們用 `?` 表示可選的參數: ```ts function buildName(firstName: string, lastName?: string) { if (lastName) { return firstName + ' ' + lastName; } else { return firstName; } } let tomcat = buildName('Tom', 'Cat'); let tom = buildName('Tom'); ``` 需要注意的是,可選參數必須接在必需參數后面。換句話說,**可選參數后面不允許再出現必需參數了**: ```ts function buildName(firstName?: string, lastName: string) { if (firstName) { return firstName + ' ' + lastName; } else { return lastName; } } let tomcat = buildName('Tom', 'Cat'); let tom = buildName(undefined, 'Tom'); // index.ts(1,40): error TS1016: A required parameter cannot follow an optional parameter. ``` ## 參數默認值 在 ES6 中,我們允許給函數的參數添加默認值,**TypeScript 會將添加了默認值的參數識別為可選參數**: ```ts function buildName(firstName: string, lastName: string = 'Cat') { return firstName + ' ' + lastName; } let tomcat = buildName('Tom', 'Cat'); let tom = buildName('Tom'); ``` 此時就不受「可選參數必須接在必需參數后面」的限制了: ```ts function buildName(firstName: string = 'Tom', lastName: string) { return firstName + ' ' + lastName; } let tomcat = buildName('Tom', 'Cat'); let cat = buildName(undefined, 'Cat'); ``` > 關于默認參數,可以參考 [ES6 中函數參數的默認值][]。 ## 剩余參數 ES6 中,可以使用 `...rest` 的方式獲取函數中的剩余參數(rest 參數): ```js function push(array, ...items) { items.forEach(function(item) { array.push(item); }); } let a: any[] = []; push(a, 1, 2, 3); ``` 事實上,`items` 是一個數組。所以我們可以用數組的類型來定義它: ```ts function push(array: any[], ...items: any[]) { items.forEach(function(item) { array.push(item); }); } let a = []; push(a, 1, 2, 3); ``` 注意,rest 參數只能是最后一個參數,關于 rest 參數,可以參考 [ES6 中的 rest 參數][]。 ## 重載 重載允許一個函數接受不同數量或類型的參數時,作出不同的處理。 比如,我們需要實現一個函數 `reverse`,輸入數字 `123` 的時候,輸出反轉的數字 `321`,輸入字符串 `'hello'` 的時候,輸出反轉的字符串 `'olleh'`。 利用聯合類型,我們可以這么實現: ```ts function reverse(x: number | string): number | string { if (typeof x === 'number') { return Number(x.toString().split('').reverse().join('')); } else if (typeof x === 'string') { return x.split('').reverse().join(''); } } ``` **然而這樣有一個缺點,就是不能夠精確的表達,輸入為數字的時候,輸出也應該為數字,輸入為字符串的時候,輸出也應該為字符串。** 這時,我們可以使用重載定義多個 `reverse` 的函數類型: ```ts function reverse(x: number): number; function reverse(x: string): string; function reverse(x: number | string): number | string { if (typeof x === 'number') { return Number(x.toString().split('').reverse().join('')); } else if (typeof x === 'string') { return x.split('').reverse().join(''); } } ``` 上例中,我們重復定義了多次函數 `reverse`,前幾次都是函數定義,最后一次是函數實現。在編輯器的代碼提示中,可以正確的看到前兩個提示。 注意,TypeScript 會優先從最前面的函數定義開始匹配,所以多個函數定義如果有包含關系,需要優先把精確的定義寫在前面。 ## 參考 - [Functions](http://www.typescriptlang.org/docs/handbook/functions.html)([中文版](https://zhongsp.gitbooks.io/typescript-handbook/content/doc/handbook/Functions.html)) - [Functions # Function Types](http://www.typescriptlang.org/docs/handbook/interfaces.html#function-types)([中文版](https://zhongsp.gitbooks.io/typescript-handbook/content/doc/handbook/Interfaces.html#函數類型)) - [JS 函數式編程指南](https://llh911001.gitbooks.io/mostly-adequate-guide-chinese/content/) - [ES6 中的箭頭函數] - [ES6 中函數參數的默認值] - [ES6 中的 rest 參數] [ES6 中的箭頭函數]: http://es6.ruanyifeng.com/#docs/function#箭頭函數 [ES6 中函數參數的默認值]: http://es6.ruanyifeng.com/#docs/function#函數參數的默認值 [ES6 中的 rest 參數]: http://es6.ruanyifeng.com/#docs/function#rest參數 --- - [上一章:數組的類型](type-of-array.md) - [下一章:類型斷言](type-assertion.md)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看