当前位置:网站首页>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会产生错误。
边栏推荐
- Mathematical Principles of Graph Convolutional Neural Networks——A Preliminary Study on Spectral Graph Theory and Fourier Transform
- ARC在编译期和运行期做了什么
- Web 3.0入门教程
- (18)[系统调用]追踪系统调用(服务表)
- 浅谈在线编辑器中增量编译技术的应用
- Research on intelligent charging strategy of matlab simulink lithium-ion battery
- Tensorflow模型量化(Quantization)原理及其实现方法
- 公司部门来了个00后测试卷王之王,老油条表示真干不过,已经...
- esp32系列(5):esp32 蓝牙架构学习
- Valid bracketed strings [greedy exercise]
猜你喜欢

BCryptPasswordEncoder的使用及原理
![(17)[系统调用]追踪系统调用(0环)](/img/d4/aa48745ac918ebfc45c07b587fa86f.png)
(17)[系统调用]追踪系统调用(0环)

主流的深度学习推理架构有哪些呢?

莫队--优雅的暴力
![Valid bracketed strings [greedy exercise]](/img/1c/5cefb53bc4aba54dd79b0cc9b09b0d.png)
Valid bracketed strings [greedy exercise]

【综合类型第 34 篇】喜讯!喜讯!!喜讯!!!,我在 CSDN 的第一个实体铭牌

一个 15 年 SAP ABAP 开发人员分享的 SAPGUI 一些个性化设置和实用小技巧试读版

【网络工程】A、B、C、D、E类IP地址划分依据和特殊的IP地址

Insert data into MySQL in C language

升级 MDK 5.37 后的问题处理: AC6编译选项, printf, 重启失效等
随机推荐
记者卧底
数据库系统原理与应用教程(068)—— MySQL 练习题:操作题 90-94(十二):DML 语句练习
数据预处理:离散特征编码方法
ERROR 2003 (HY000) Can't connect to MySQL server on 'localhost3306' (10061)Solution
JMeter笔记4 | JMeter界面介绍
【牛客编程题】GO语言入门46题
知识蒸馏2:目标检测中的知识蒸馏
C陷阱与缺陷 第7章 可移植性缺陷 7.2 标识符名称的限制
(17)[系统调用]追踪系统调用(0环)
Mathematical Principles of Graph Convolutional Neural Networks——A Preliminary Study on Spectral Graph Theory and Fourier Transform
un7.30:linux——如何在docker容器中安装MySQL?
How Google earth engine realizes the arrangement and selection of our time list
2022年杭电多校第2场 1001 Static Query on Tree(树链剖分+哈希表差分
shell快速移植
快使用flyway管理sql脚本吧~
crontab报错,但本地执行正常
Error occurred while trying to proxy request The project suddenly can't get up
信息学奥赛一本通 1966:【14NOIP普及组】比例简化 | 洛谷 P2118 [NOIP2014 普及组] 比例简化
自动化早已不是那个自动化了,谈一谈自动化测试现状和自我感受……
知识蒸馏1:基础原理讲解及yolov5项目实战介绍