当前位置:网站首页>LayaBox---TypeScript---函数
LayaBox---TypeScript---函数
2022-07-30 17:38:00 【格拉格拉】
在ts中虽然已经支持类、命名空间和模块,但是函数仍然是主要的定义行为的地方。
目录
1.函数
和JavaScript一样,TypeScript函数可以创建有名字的函数和匿名函数。
// Named function
function add(x, y) {
return x + y;
}
// Anonymous function
let myAdd = function(x, y) { return x + y; };2.函数类型
让我们为上面那个函数添加类型:
function add(x: number, y: number): number {
return x + y;
}
let myAdd = function(x: number, y: number): number { return x + y; };我们可以给每个参数添加类型之后再为函数本身添加返回值类型。 TypeScript能够根据返回语句自动推断出返回值类型,因此我们通常省略它。
函数的完整类型
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; };推断类型:
如果你在赋值语句的一边指定了类型但是另一边没有类型的话,TypeScript编译器会自动识别出类型:
// myAdd has the full function type
let myAdd = function(x: number, y: number): number { return x + y; };
// The parameters `x` and `y` have the type number
let myAdd: (baseValue: number, increment: number) => number =
function(x, y) { return x + y; };
这叫做“按上下文归类”,是类型推论的一种。 它帮助我们更好地为程序指定类型。3.可选参数和默认参数
传递给一个函数的参数个数必须与函数期望的参数个数一致。
function buildName(firstName: string, lastName: string) {
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"); // ah, just rightjs里每个参数都是可选的,可传可不传。没传的时候它的值就是undefined.
ts里可以值参数名后使用“?”实现可选参数的功能。
function buildName(firstName: string, lastName?: string) {
if (lastName)
return firstName + " " + lastName;
else
return firstName;
}
let result1 = buildName("Bob"); // works correctly now
let result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
let result3 = buildName("Bob", "Adams"); // ah, just right在TypeScript里,我们也可以为参数提供一个默认值当用户没有传递这个参数或传递的值是undefined时。 它们叫做有默认初始化值的参数。 让我们修改上例,把last name的默认值设置为"Smith"。
function buildName(firstName: string, lastName = "Smith") {
return firstName + " " + lastName;
}
let result1 = buildName("Bob"); // works correctly now, returns "Bob Smith"
let result2 = buildName("Bob", undefined); // still works, also returns "Bob Smith"
let result3 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
let result4 = buildName("Bob", "Adams"); // ah, just right️注意:与普通可选参数不同的是,带默认值的参数不需要放在必须参数的后面。 如果带默认值的参数出现在必须参数前面,用户必须明确的传入 undefined值来获得默认值。
4.剩余参数
当你想同时操作多个参数,或者你并不知道会有多少参数传递进来。
在JavaScript里,你可以使用 arguments来访问所有传入的参数。
在TypeScript里,你可以把所有参数收集到一个变量里:
function buildName(firstName: string, ...restOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
剩余参数会被当做个数不限的可选参数。 可以一个都没有,同样也可以有任意个。
编译器创建参数数组,名字是你在省略号( ...)后面给定的名字,你可以在函数体内使用这个数组。
这个省略号也会在带有剩余参数的函数类型定义上使用到:
function buildName(firstName: string, ...restOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
let buildNameFun: (fname: string, ...rest: string[]) => string = buildName;this和箭头函数
let deck = {
suits: ["hearts", "spades", "clubs", "diamonds"],
cards: Array(52),
createCardPicker: function() {
return function() {
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);
可以看到createCardPicker是个函数,并且它又返回了一个函数。 如果我们尝试运行这个程序,
会发现它并没有弹出对话框而是报错了。 因为 createCardPicker返回的函数里的this被设置成
了window而不是deck对象。 因为我们只是独立的调用了 cardPicker()。 顶级的非方法式调用会
将 this视为window。 (注意:在严格模式下, this为undefined而不是window)。
为了解决这个问题,我们可以在函数被返回时就绑好正确的this。 这样的话,无论之后怎么使用它,
都会引用绑定的‘deck’对象。 我们需要改变函数表达式来使用ECMAScript 6箭头语法。 箭头函数
能保存函数创建时的 this值,而不是调用时的值:
let deck = {
suits: ["hearts", "spades", "clubs", "diamonds"],
cards: Array(52),
createCardPicker: function() {
// NOTE: the line below is now an arrow function, allowing us to capture 'this' right here
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);5.重载
JavaScript本身是个动态语言。 JavaScript里函数根据传入不同的参数而返回不同类型的数据是很常见的。
let suits = ["hearts", "spades", "clubs", "diamonds"];
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);
pickCard方法根据传入参数的不同会返回两种不同的类型。 如果传入的是代表纸牌的对象,
函数作用是从中抓一张牌。 如果用户想抓牌,我们告诉他抓到了什么牌。
但是这怎么在类型系统里表示呢,下面我们来重载 pickCard函数。
let suits = ["hearts", "spades", "clubs", "diamonds"];
function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
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);这样改变后,重载的pickCard函数在调用的时候会进行正确的类型检查。
️注意:function pickCard(x): any并不是重载列表的一部分,
这里只有两个重载:一个是接收对象另一个接收数字。 以其它参数调用 pickCard会产生错误。
边栏推荐
- LeetCode 952. 按公因数计算最大组件大小
- 查询表中开始日期与结束日期
- 论文阅读之《Color Constancy Using CNNs》
- un7.30:Linux——如何在docker容器中显示MySQL的中文字符?
- 数据库系统原理与应用教程(065)—— MySQL 练习题:操作题 62-70(九):分组查询与子查询
- C陷阱与缺陷 第7章 可移植性缺陷 7.2 标识符名称的限制
- fast shell porting
- 一个 15 年 SAP ABAP 开发人员分享的 SAPGUI 一些个性化设置和实用小技巧试读版
- Shell implementation based on stm32
- 数据预处理:离散特征编码方法
猜你喜欢

JMeter笔记3 | JMeter安装和环境说明

浅谈在线编辑器中增量编译技术的应用

关于内和调试无法查看ntdll内存的问题

Express framework connects MySQL and ORM framework

论文阅读之《Underwater scene prior inspired deep underwater image and video Enhancement (UWCNN)》

基于模糊PID的液压舵机伺服系统

Error occurred while trying to proxy request项目突然起不来了

Web 3.0入门教程

JMeter笔记4 | JMeter界面介绍

Shell implementation based on stm32
随机推荐
自动化早已不是那个自动化了,谈一谈自动化测试现状和自我感受……
S7-200SMART中定时器的使用方法和常见注意事项汇总
数据库系统原理与应用教程(064)—— MySQL 练习题:操作题 51-61(八):查询条件的构造、通配符
数据库系统原理与应用教程(067)—— MySQL 练习题:操作题 82-89(十一):数据的增、删、改操作
Express framework connects MySQL and ORM framework
un7.30:Linux——如何在docker容器中显示MySQL的中文字符?
习题:变量、常量和基本数据类型
LeetCode167: Sum of two numbers in sorted array
LeetCode318: Maximum product of word lengths
【牛客编程题】GO语言入门46题
有效的括号字符串[贪心练习]
fast shell porting
简易的命令行入门教程
首发!阿里技术大牛最新耗时半个月整理出最全MySQL性能优化和高可用架构技术宝典,直接封神!
什么是无损检测设备?
【网络工程】A、B、C、D、E类IP地址划分依据和特殊的IP地址
PLSQL Developer安装和配置
图卷积神经网络的数学原理——谱图理论和傅里叶变换初探
测试行业干了5年,从只会点点点到了现在的测试开发,总算是证明了自己
知识蒸馏2:目标检测中的知识蒸馏