一、函数
// 有名字的函数function add(x, y) {return x + y;}// 匿名函数let myAdd = function(x, y) { return x + y; };
二、函数类型
函数类型包含两部分:参数类型和返回值类型
function add(x: number, y: number): number {return x + y;}let myAdd = function(x: number, y: number): number { return x + y; };// 书写完整函数类型let myAdd: (x:number, y:number) => number =function(x: number, y: number): number { return x + y; };// 或let myAdd: (baseValue: number, increment: number) => number =function(x: number, y: number): number { return x + y; };// 推断类型// 自动推断上下文,myAdd没有申明类型,靠后面的推断的let myAdd = function(x: number, y: number): number { return x + y; };// 完整申明let myAdd: (baseValue: number, increment: number) => number =function(x, y) { return x + y; };
ps):注意:TypeScript 能够根据返回语句自动推断出返回值类型,因此我们通常省略它。
三、可选参数和默认参数
1,可选参数:在参数名旁使用 ? 实现可选参数的功能,并且可选参数必须跟在必须参数后面
2,默认参数:提供默认值,当用户没有传递这个参数或传递的值是 undefined 时。 它们叫做有默认初始化值的参数。
function buildName(firstName: string, lastName?: string) { // 可选参数,必须在必须参数后面// ...}function buildName(firstName = "Will", lastName: string) {// 默认参数,可以在前面,但如果不传必须写上undefinedreturn firstName + " " + lastName;}let result1 = buildName("Bob"); // error, too few parameterslet result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameterslet result3 = buildName("Bob", "Adams"); // okay and returns "Bob Adams"let result4 = buildName(undefined, "Adams"); // okay and returns "Will Adams"
四、剩余参数
把未知的参数用”…”收起来
function buildName(firstName: string, ...restOfName: string[]) {return firstName + " " + restOfName.join(" ");}let buildNameFun: (fname: string, ...rest: string[]) => string = buildName;
五、this
普通函数:js函数里面的this是被调用的时候才会指定,优点是方法只会被创建一次,会添加到对象的原型链上。 它们在不同对象间是共享的。
尖头函数:里面的this指向上一级的this,缺点是,每次实例化一个对象都会创建一个箭头函数
// 1,js定义// this内部工作原理function hello(thing) {console.log("Hello " + thing);}// this指向windowhello("world")// 相当于hello.call(window, "world");// 2,ts定义interface Card {suit: string;card: number;}interface Deck {suits: string[];cards: number[];createCardPicker(this: Deck): () => Card;}let deck: Deck = {suits: ["hearts", "spades", "clubs", "diamonds"],cards: Array(52),createCardPicker: function(this: Deck) { // 显示的指定函数的this是Deck类型return () => {let pickedCard = Math.floor(Math.random() * 52);let pickedSuit = Math.floor(pickedCard / 13);return {suit: this.suits[pickedSuit], card: pickedCard % 13};}}}let cardPicker = deck.createCardPicker();let pickedCard = cardPicker();alert("card: " + pickedCard.card + " of " + pickedCard.suit);
六、重载
方法是为同一个函数提供多个函数类型定义来进行函数重载。 编译器会根据这个列表去处理函数的调用
let suits = ["hearts", "spades", "clubs", "diamonds"];function pickCard(x: {suit: string; card: number; }[]): number; // 函数类型定义1function pickCard(x: number): {suit: string; card: number; }; // 函数类型定义2function pickCard(x): any {// Check to see if we're working with an object/array// if so, they gave us the deck and we'll pick the cardif (typeof x == "object") {let pickedCard = Math.floor(Math.random() * x.length);return pickedCard;}// Otherwise just let them pick the cardelse if (typeof x == "number") {let pickedSuit = Math.floor(x / 13);return { suit: suits[pickedSuit], card: x % 13 };}}let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }];let pickedCard1 = myDeck[pickCard(myDeck)];alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);let pickedCard2 = pickCard(15);alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);// 注意:调用函数检查类型的时候,它查找重载列表,尝试使用第一个重载定义。 如果匹配的话就使用这个。 因此,在定义重载的时候,一定要把最精确的定义放在最前面。
