一、函数
// 有名字的函数
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) {// 默认参数,可以在前面,但如果不传必须写上undefined
return firstName + " " + lastName;
}
let result1 = buildName("Bob"); // error, too few parameters
let result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
let 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指向window
hello("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; // 函数类型定义1
function pickCard(x: number): {suit: string; card: number; }; // 函数类型定义2
function 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 card
if (typeof x == "object") {
let pickedCard = Math.floor(Math.random() * x.length);
return pickedCard;
}
// Otherwise just let them pick the card
else 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);
// 注意:调用函数检查类型的时候,它查找重载列表,尝试使用第一个重载定义。 如果匹配的话就使用这个。 因此,在定义重载的时候,一定要把最精确的定义放在最前面。