《前端之路》- TypeScript(二) 函數篇

1、定義函數方法

在 es5 中定時函數的方法有 命名函數和函數表達式(匿名函數)這門兩種。那麼一樣的,在 TypeScript 中,函數的定義是什麼樣子的呢?javascript

1-1 命名函數

這裏須要注意的一點是: viod 類型,是函數不返回任何類型數據
複製代碼

TypeScript 語法前端

function func1(): string {
	return '213';
}

function func2(): number {
	return 123;
}

function func3(): Array<any> {
	return [123, {}];
}

function func4(): Array<number> {
	return [123, 456];
}

function func5(): Array<string> {
	return ['123', '1233'];
}

function func6(): void {
	console.log(123);
}
複製代碼

被編譯成 ES5JavaScriptjava

"use strict";
function func1() {
    return '213';
}
function func2() {
    return 123;
}
function func3() {
    return [123, {}];
}
function func4() {
    return [123, 456];
}
function func5() {
    return ['123', '1233'];
}
function func6() {
    console.log(123);
}
複製代碼

1-2 函數表達式

這裏須要簡單的普及一個 ES6 的箭頭函數,無大括號時,直接表示 return 這個值。
複製代碼

TypeScript 語法git

const fun11 = (): string => {
	return '123';
};

const fun12 = (): string => '123';

const fun13 = (): any => [123, '123'];

const fun14 = function(): string {
	return '123';
};

const fun15 = function(): any {
	return { name: 123 };
};

複製代碼

被編譯成 ES5JavaScriptgithub

"use strict";
var fun11 = function () {
    return '123';
};
var fun12 = function () { return '123'; };
var fun13 = function () { return [123, '123']; };
var fun14 = function () {
    return '123';
};
var fun15 = function () {
    return { name: 123 };
};
複製代碼

2、定義函數傳參

2-1 定義函數傳參

這裏須要簡單的描述下,函數的傳參的類型和以前文章中介紹到的數據類型定義方式是一致的。
複製代碼

TypeScript 語法typescript

const parasFun1 = (x: string, y: number) => {
	console.log(x + y);
};

let res1 = parasFun1('1', 2); // 猜猜返回啥?哈哈哈哈 能夠子啊留言中寫下你的答案
複製代碼

被編譯成 ES5JavaScript函數

"use strict";
var parasFun1 = function (x, y) {
    console.log(x + y);
};
var res1 = parasFun1('1', 2); // 猜猜返回啥?哈哈哈哈 能夠子啊留言中寫下你的答案
複製代碼

3、可選傳參

3-1 定義函數的可選傳參

這裏須要簡單的描述下,函數的可選參數,很明顯就是能夠選擇傳入這個參數也能夠選擇不傳入這個參數,且可選參數必定是排在必傳參數的後面。
複製代碼

TypeScript 語法ui

const parmaFunc1 = (name: string, age?: number) => {
	if (age) {
		return `個人名字是:${name} --- 個人年齡是: ${age}`;
	} else {
		return `個人名字是:${name} --- 個人年齡保密!`;
	}
};

let res11 = parmaFunc1('zhangsan', 123);
let res12 = parmaFunc1('zhangsan');

const parmaFunc2 = (name?: string, age: number) => {
	if (age) {
		return `個人名字是:${name} --- 個人年齡是: ${age}`;
	} else {
		return `個人名字是:${name} --- 個人年齡保密!`;
	}
};
// 這裏的 parmaFunc2 會報錯麼?
複製代碼

被編譯成 ES5JavaScriptes5

"use strict";
var parmaFunc1 = function (name, age) {
    if (age) {
        return "\u6211\u7684\u540D\u5B57\u662F\uFF1A" + name + " --- \u6211\u7684\u5E74\u9F84\u662F\uFF1A " + age;
    }
    else {
        return "\u6211\u7684\u540D\u5B57\u662F\uFF1A" + name + " --- \u6211\u7684\u5E74\u9F84\u4FDD\u5BC6\uFF01";
    }
};
var res11 = parmaFunc1('zhangsan', 123);
var res12 = parmaFunc1('zhangsan');
複製代碼

4、默認傳參

4-1 定義函數默認傳參

這裏的默認傳參和 ES6 中默認傳參的使用方式是一致的
複製代碼

TypeScript 語法spa

const defaultParamFunc1 = (x: string, age: number = 10): void => {
	console.log(`個人名字是:${name} --- 個人年齡是: ${age}`);
};

let defaultRes1 = defaultParamFunc1('zhangsan');
// 這裏會打印出什麼呢?
複製代碼

被編譯成 ES5JavaScript

"use strict";
var defaultParamFunc1 = function (x, age) {
    if (age === void 0) { age = 10; }
    console.log("\u6211\u7684\u540D\u5B57\u662F\uFF1A" + name + " --- \u6211\u7684\u5E74\u9F84\u662F\uFF1A " + age);
};
var defaultRes1 = defaultParamFunc1('zhangsan');

複製代碼

5、傳遞剩餘參數

5-1 定義函數傳遞剩餘參數(三點運算符)

這裏的傳遞剩餘參數和 ES6 中傳遞剩餘參數的使用方式是一致的,只不過咱們可能須要對剩餘參數進行一個類型的定義
複製代碼

TypeScript 語法

// 寫一個demo 就是,咱們須要對一個對個求和,且咱們不知道具體會有多少個參數

const restParamsFunc1 = (x: any, y: any, z: any): number => {
	return x + y + z;
};
let restRes1 = restParamsFunc1(1, 2, 3); // 正常運行

// let restRes2 = restParamsFunc1(1, 2, 3, 4); // ts 會報錯,說第四個參數未聲明

const restParamsFunc2 = (...res: number[]): number => {
	let sum = 0;
	for (let index = 0; index < res.length; index++) {
		sum += res[index];
	}
	return sum;
};
let restRes3 = restParamsFunc2(1, 2, 3, 4); // 這個時候又會得出什麼結果呢?

複製代碼

被編譯成 ES5JavaScript

"use strict";
// 寫一個demo 就是,咱們須要對一個對個求和,且咱們不知道具體會有多少個參數
var restParamsFunc1 = function (x, y, z) {
    return x + y + z;
};
var restRes1 = restParamsFunc1(1, 2, 3); // 正常運行
// let restRes2 = restParamsFunc1(1, 2, 3, 4); // ts 會報錯,說第四個參數未聲明
var restParamsFunc2 = function () {
    var res = [];
    for (var _i = 0; _i < arguments.length; _i++) {
        res[_i] = arguments[_i];
    }
    var sum = 0;
    for (var index = 0; index < res.length; index++) {
        sum += res[index];
    }
    return sum;
};
var restRes3 = restParamsFunc2(1, 2, 3, 4); // 這個時候又會得出什麼結果呢?
複製代碼

6、函數重載

6-1 JavaScript 中的函數重載

函數名稱相同,可是函數的傳入參數不一樣。執行不一樣的功能,這個時候就會出現函數重載。

TypeScript 語法

const reloadFunc1 = (name: string) => {
	console.log(name);
};
const reloadFunc1 = (age: string) => {
	console.log(age);
};
const reloadFunc1 = (name: string, age: number) => {
	if (age) {
		console.log(name, age);
	} else {
		console.log(name);
	}
};

// 這個時候咱們會發現 ts 已經給咱們報了語法的錯誤,可是轉譯成 es5 的代碼的時候依然能夠運行,只不事後面定義的方式會覆蓋前面定義的同名函數的方法

複製代碼

被編譯成 ES5JavaScript

"use strict";
var reloadFunc1 = function (name) {
    console.log(name);
};
var reloadFunc1 = function (age) {
    console.log(age);
};
var reloadFunc1 = function (name, age) {
    if (age) {
        console.log(name, age);
    }
    else {
        console.log(name);
    }
};
// 這個時候咱們會發現 ts 已經給咱們報了語法的錯誤,可是轉譯成 es5 的代碼的時候依然能夠運行,只不事後面定義的方式會覆蓋前面定義的同名函數的方法
複製代碼

這裏咱們須要區分一下 Java 中的函數重載和 ts 中的函數重載的區別

  • 在 Java 中 定義的同名重載函數,會根據傳入數據類型的差別,直接執行對應的函數,可是 ts 不會。
  • 在 ts 中,即便定義了重載函數,編譯成 ES5 之後,仍是隻剩下一個對應函數的判斷。這裏咱們只作一個簡單的瞭解,在前端寫 JS 的時候仍是須要注意命名空間和命名重疊的問題。

咱們仍是以代碼的例子來作區分,例子一以下:

TypeScript 語法

const reloadFunc2 = (name: string):string;
const reloadFunc2 = (age: number):number;
const reloadFunc2 = (age:any):any => {
    if(typeof age === 'number') {
        console.log(name, age)
    }  else {
        console.log(name)
    }
}

// 這個時候,ts 依然會報錯,是爲何? 這裏就要提到 const 、let 的做用域的問題,由於這裏也是 ES6 的基礎知識,不展開來講了。
複製代碼

被編譯成 ES5JavaScript

var reloadFunc2 = function (name) { return ; };
var reloadFunc2 = function (age) { return ; };
var reloadFunc2 = function (age) {
    if (typeof age === 'number') {
        console.log(name, age);
    }
    else {
        console.log(name);
    }
};
複製代碼

咱們仍是以代碼的例子來作區分,例子二以下:

TypeScript 語法

function reloadFunc3(name: string):string; 
function reloadFunc3(age: number):number;
function reloadFunc3(str:any):any {
    if(typeof str === 'number') {
        console.log(name, str)
    }  else {
        console.log(name)
    }
}; 
複製代碼

被編譯成 ES5JavaScript

function reloadFunc3(str) {
    if (typeof str === 'number') {
        console.log(name, str);
    }
    else {
        console.log(name);
    }
}

// 這裏編譯出來,竟然只有一個函數,驚歎了,爲何驚歎了呢?由於這裏和 Java 中的函數重載差異有點大。
複製代碼

7、箭頭函數

7-1 定義箭頭函數

箭頭函數的話,其實和 ES6 中的寫法是一致的,而後須要咱們注意的是,箭頭函數中的上下文,指向的是起父級函數的上下文。

TypeScript 語法

const arrowFunc = (): number => {
	return 123;
};

setTimeout(() => {
	console.log('過了一秒');
}, 1000);

複製代碼

被編譯成 ES5JavaScript

"use strict";
var arrowFunc = function () {
    return 123;
};
setTimeout(function () {
    console.log('過了一秒');
}, 1000);
複製代碼

8、總結

這一篇文章也只能算是基礎入門級別的 ts 中函數的定義方式和方法,這個須要你們在平常的項目中多書寫,才能避免一些問題,而後咱們就會發現,咱們在使用 ts 去書寫一些函數和對應參數的時候,咱們已經能夠避免一些多餘參數和錯誤的參數類型的傳入致使的一些奇奇怪怪的bug。好了,這一章就先寫到這裏。


GitHub 地址:(歡迎 star 、歡迎推薦 : ) 《前端之路》 - TypeScript(二)函數篇

相關文章
相關標籤/搜索