【TS】九天学会TS语法——3.TypeScript 函数

news2024/11/25 16:35:19

今天学习 TypeScript 的函数,包括函数类型、可选参数、默认参数、剩余参数。

  1. 函数声明和表达式
  2. 函数类型
  3. 可选参数和默认参数
  4. 剩余参数

在 TypeScript 中,函数是编程的核心概念之一。它们允许我们将代码组织成可重用的块,并提供了强大的抽象能力。在本文中,我们将深入探讨 TypeScript 函数的各种特性,包括函数类型、可选参数、默认参数和剩余参数。

一.函数声明和表达式

在 TypeScript 中,我们可以通过函数声明函数表达式来定义函数。函数声明具有函数名,而函数表达式则没有。

// 函数声明
// 定义了一个名为 add 的函数,它接受两个数字类型的参数 a 和 b
// 并返回它们的和,返回值类型也是数字
function add(a: number, b: number): number {
    return a + b; // 返回参数 a 和 b 的和
}

// 函数表达式
// 定义了一个匿名函数并将其赋值给变量 subtract
// 这个函数接受两个数字类型的参数 a 和 b,并返回它们的差,返回值类型也是数字
const subtract = (a: number, b: number): number => {
    return a - b; // 返回参数 a 减去 b 的结果
};

(1)函数声明

  1. 使用 function 关键字来声明。
  2. 函数声明会被提升,可以在声明之前调用它。
  3. 通常用于顶层作用域或模块中。
greet('清清ww'); // 输出: Hello, 清清ww!

function greet(name) {
  console.log('Hello, ' + name + '!');
}

greet('清清ww'); // 输出: Hello, 清清ww!

在这个例子中,我们定义了一个名为 greet 的函数,它接受一个参数 name 并打印一条问候语。由于函数声明会被提升,我们可以在声明之前调用 greet 函数。

(2)函数表达式

  1. 使用变量赋值的方式来定义函数。
  2. 函数表达式不会提升,必须在定义之后才能调用。
  3. 可以立即调用或作为匿名函数传递给其他函数。
const greet = function(name) {
  console.log('Hello, ' + name + '!');
};

greet('清清ww'); // 输出: Hello, 清清ww!

在这个例子中,我们使用了一个函数表达式来定义一个匿名函数,并将其赋值给变量 greet。然后通过变量名 greet 来调用这个函数。由于函数表达式不会被提升,我们不能在声明之前调用它。

二.函数类型

TS 允许我们为函数定义类型。函数类型包括参数类型和返回类型。

在 TypeScript 中,函数类型是指函数的参数类型返回类型的组合。TypeScript 允许我们为函数定义类型,以确保函数的参数和返回值符合预期的类型。函数类型通常用于函数声明、函数表达式和箭头函数。

1.函数类型声明

函数类型声明是一种显式指定函数参数类型和返回类型的方式。它使用 function 关键字,后跟参数列表和返回类型。

// 函数类型声明
let greet: (name: string) => string;

// 函数实现
greet = function(name: string): string {
  return 'Hello, ' + name + '!';
};

const message = greet('清清ww');
console.log(message); // 输出: Hello, 清清ww!

在上面的例子中,我们首先声明了一个函数类型 greet,它接受一个 string 类型的参数 name,并返回一个 string 类型的值。然后,我们为 greet 赋予了一个具体的函数实现。

2.函数类型表达式

函数类型表达式是一种更简洁的函数类型声明方式。它使用箭头函数语法 => 来定义函数类型。

// 函数类型表达式
let greet: (name: string) => string;

// 函数实现
greet = (name: string): string => {
  return 'Hello, ' + name + '!';
};

const message = greet('清清ww');
console.log(message); // 输出: Hello, 清清ww!

在上面的例子中,我们使用箭头函数语法来定义函数类型 greet。这种方式更加简洁,但功能与函数类型声明相同。

3.函数类型推断

TypeScript 具有类型推断功能,它可以根据函数的实现自动推断函数的类型。如果没有显式指定函数类型,TypeScript 会尝试推断函数的类型。

// 函数类型推断
let greet = function(name: string): string {
  return 'Hello, ' + name + '!';
};

const message = greet('清清ww');
console.log(message); // 输出: Hello, 清清ww!

在上面的例子中,我们没有显式指定函数类型,但 TypeScript 会根据函数的实现自动推断函数的类型。

三.可选参数和默认参数

TypeScript 允许我们定义可选参数和默认参数。可选参数在函数调用时可以省略,而默认参数在未提供值时使用默认值。

1.可选参数

可选参数是指在调用函数时可以省略的参数,通过在参数后面添加一个问号 ? 来表示该参数是可选的。可选参数通常位于参数列表的末尾。

// 可选参数
function greet(name: string, age?: number): string {
  if (age) {
    return `你好${name},你${age} 岁了!`;
  } else {
    return `你好, ${name}!`;
  }
}

console.log(greet('清清ww')); // 输出: 你好, 清清ww!
console.log(greet('清清ww', 3)); // 输出: 你好, 清清ww, 你3岁了!

在上面的例子中,greet 函数的 age 参数是可选的。当调用 greet 函数时,如果没有提供 age 参数,函数会返回一个没有年龄信息的问候。

2.默认参数

默认参数是指在调用函数时如果没有提供该参数,则使用默认值的参数。在 TypeScript 中,通过在参数后面赋值来设置默认值。

// 默认参数
function greet(name: string, age: number = 3): string {
  return `你好, ${name}, 你${age}岁了!`;
}

console.log(greet('清清ww')); // 输出: 你好, 清清ww, 你3岁了!
console.log(greet('清清ww', 3)); // 输出: 你好, 清清ww, 你3岁了!

在上面的例子中,greet 函数的 age 参数有一个默认值 3。当调用 greet 函数时,如果没有提供 age 参数,函数会使用默认值 3

3. 可选参数和默认值的优先级

当同时使用可选参数和默认值时,它们的优先级是按照参数的顺序来确定的。

  1. 如果一个参数既有默认值又是可选的,那么在调用函数时,如果省略了这个参数,就会使用默认值。
  2. 如果一个参数是可选的但没有默认值,那么在调用函数时,可以省略这个参数,函数会将其视为 undefined
  3. 如果一个参数有默认值但不是可选的,那么在调用函数时,必须提供这个参数的值,否则会使用默认值。
// 可选参数和默认参数的优先级
function greet(name: string, age?: number = 3): string {
  return `你好, ${name}, 你${age} 岁了!`;
}

console.log(greet('清清ww')); // 输出: 你好, 清清ww, 你3岁了!
console.log(greet('清清ww', undefined)); // 输出: 你好, 清清ww, 你3岁了!
console.log(greet('清清ww', 4)); // 输出: 你好, 清清ww, 你4岁了!

在上面的例子中,age 参数既被标记为可选,又被赋予了默认值3。当调用 greet 函数时,如果没有提供 age 参数,函数会使用默认值3。如果提供了 age 参数,即使值为 undefined,函数也会使用默认值 3

四.剩余参数

剩余参数是通过在参数名前加上三个点(…)来定义的,并且它必须是函数的最后一个参数。它允许我们将多个参数收集到一个数组中(在处理不确定数量的参数时非常有用)。这样就可以在函数内部使用这个参数作为数组来访问所有的剩余参数。

举个例子:一个名为 createPerson 的函数,它接受一个对象和一个剩余参数:

// 定义一个 Person 类型,包含 name, age 和可选的 hobbies 数组
type Person = {
    name: string;
    age: number;
    hobbies?: string[];
};

// 定义一个函数 createPerson,接受一个 Person 类型的对象和剩余的字符串参数作为爱好
function createPerson(person: Person, ...hobbies: string[]): Person {
    // 检查是否有提供爱好
    if (hobbies.length > 0) {
        // 如果有爱好,将它们赋值给 person 对象的 hobbies 属性
        person.hobbies = hobbies;
    }
    // 返回修改后的 person 对象
    return person;
}

// 创建一个基础的人物对象,包含 name 和 age 属性
let basePerson: Person = {
    name: '清清ww',
    age: 3,
};

// 使用 createPerson 函数添加额外的爱好,剩余参数 'eat', 'play', 'sleep' 被视为一个数组
let personWithHobbies = createPerson(basePerson, 'eat', 'play', 'sleep');

// 打印包含爱好的 person 对象
console.log(personWithHobbies);

在这个例子中,createPerson 函数接受一个 Person 类型的对象和一个剩余参数 。剩余参数是一个二维数组,其中每个元素是一个 [key, value] 对,用于添加或更新 Person 对象的属性。

调用 createPerson 函数时,我们首先创建了一个基础的人物对象 basePerson,然后使用剩余参数添加了爱好 hobbies。打印出的personWithHobby 对象包含了所有的基础属性和额外的爱好属性。

注意:剩余参数必须是函数的最后一个参数。如果在剩余参数之后定义了其他参数,TypeScript 编译器会报错。


本文完~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2235368.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

stm32不小心把SWD和JTAG都给关了,程序下载不进去,怎么办?

因为想用STM32F103的PA15引脚,调试程序的时候不小心把SWD和JTAD接口都给关了,先看下罪魁祸首 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//关掉JTAG,不关SWGPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);//关掉SW&am…

Rust重写万物之——从头开始编写浏览器引擎

一款用 Rust 编写的全新“轮子”最近备受关注—— 因不满大公司垄断,Gosub 项目团队用 Rust 从头开始编写了一个新的浏览器引擎,目前 star 数已超过 3k。 Gosub 项目的诞生是因为不少用户对当前的 Web 浏览器现状感到不满。 尽管市面上有许多浏览器可供选择,但其中大多数…

【设计模式系列】桥接模式(十三)

一、什么是桥接模式 桥接模式(Bridge Pattern)是一种结构型设计模式,其核心目的是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式主要用于处理那些在设计时无法确定实现细节的场合,或者需要在多个实现之间…

泷羽sec学习打卡-shodan扫描4

声明 学习视频来自B站UP主 泷羽sec,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 关于shodan的那些事儿-4 一、shodan4如何查看公网ip?如何查看自己的ip?如何查看出…

杨传辉:云+AI 时代的一体化数据库|OceanBase发布会实录

在 2024 OceanBase 年度发布会 上, OceanBase CTO 杨传辉进行了主题为《云和 AI 时代的一体化数据库战略思考》的演讲,本文为演讲实录,欢迎阅读。 视频观看可点击:https://www.oceanbase.com/video/9001825 各位 OceanBase 的客…

04 深入 Oracle 并发世界:MVCC、锁、闩锁、事务隔离与并发性能优化的探索

文章目录 深入 Oracle 并发世界:MVCC、锁、闩锁、事务隔离与并发性能优化的探索一、多版本并发控制(MVCC)1.1 理论解析1.2 实践应用 二、锁与闩锁机制2.1 理论解析2.2 实践应用 三、事务隔离级别3.1 理论解析3.2 实践应用 四、死锁预防与解决…

Python-利用tkinter库编写一个exe伪恶意程序文件(下)

前言 接着上篇所讲的,我们已经完成了源代码的准备,并将其储存在了function_1.py文件中。接下来我们将把function_1.py文件编写为相对应的exe文件。那么好,废话不多说,我们直接开始。(温馨提示:由于整蛊的需…

vue使用canves把数字转成图片验证码

<canvas id"captchaCanvas" width"100" height"40"></canvas>function drawCaptcha(text) {const canvas document.getElementById(captchaCanvas);const ctx canvas.getContext(2d);// 设置背景颜色ctx.fillStyle #f0f0f0;ctx.f…

商标注册流程

个人名义&#xff08;自然人&#xff09;申请准备&#xff1a;身份证复印件(签字&#xff0c;PDF格式&#xff0c;小于2M)&#xff1b;个体户执照副本复印件(签字&#xff0c;PDF格式&#xff0c;小于2M)&#xff1b;商标图样(建议黑白JPG&#xff0c;建议尺寸800*800尺寸)。公…

《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明

参考 《element plus 使用 icon 图标(两种方式)》使用 icon 升级 Vue2 升级 Vue3 项目时&#xff0c;遇到命名时的实心与空心点差异&#xff01; ElementUI&#xff1a; 实心是 el-icon-more空心是 el-icon-more-outline ElementPlus&#xff1a; 实心是 el-icon-more-fill…

如何利用 Python 的爬虫技术获取淘宝天猫商品的价格信息?

以下是使用 Python 的爬虫技术获取淘宝天猫商品价格信息的两种常见方法&#xff1a; 方法一&#xff1a;使用 Selenium 一、环境准备&#xff1a; 安装 selenium 库&#xff1a;在命令行中运行 pip install selenium。下载浏览器驱动&#xff1a;如 ChromeDriver&#xff08;确…

Navicat for MySQL 错误:1251

mySql&#xff1a;8.4 Navicat for MySQL&#xff1a;11.0.10 企业版 绿色版 官网中关于mysql_native_password插件的说法&#xff1a;链接 1. 问题 连接数据库报错&#xff1a;1251 要求升级Navicat for MySQL 2. 原因 mysql中的mysql_native_password插件默认是关闭的 …

Android 如何写代码更少出现bug?借助IDE的检测代码质量插件来解决。

目录 前言 大家好呀~&#xff0c;我是前期后期&#xff0c;在网上冲浪的一名程序员&#xff0c;分享一些自己学到的知识&#xff0c;希望能够帮助大家节省时间。 如何写代码更少出现bug&#xff1f; 很多一些人可能会推荐我们&#xff0c;多看一些阿里巴巴的规范&#xff0c…

洛谷 P2113 看球泡妹子(DP)

传送门https://www.luogu.com.cn/problem/P2113 解题思路 可以设 表示前 场比赛看了 场&#xff0c;小红的满足度为 的最大精彩度。 然后可以枚举前面的一个比赛 &#xff0c;可以得到转移方程&#xff1a; 但是&#xff0c;我们发现数组空间有一点小大&#xff0c;可以…

HTAP数据库国产化改造技术可行性方案分析

一、现状及需求痛点 当前地市统一支撑平台是为地市租户提供全方位业务支持的核心系统&#xff0c;以满足地市级用户在业务处理、数据分析、用户服务及内部管理等多方面的需求。主要承载业务系统的联机事务处理&#xff08;OLTP&#xff09;与联机分析处理&#xff08;OLAP&…

ELK-ELK基本概念_ElasticSearch的配置

文章目录 一、什么是ELK&#xff1f;有什么用&#xff1f;ELK是什么&#xff1f;ElasticsearchLogstashKibana ELK的作用 二、ElasticSearch的安装与基本配置为何需要依赖JDK&#xff1f;使用yum install java-11-openjdk和使用Oracle官网提供的jdk的rpm包安装JDK的区别 参考资…

OpenAI大事记;GPT到ChatGPT参数量进化

目录 OpenAI大事记 GPT到ChatGPT参数量进化 OpenAI大事记 GPT到ChatGPT参数量进化 ChatGPT是从初代 GPT逐渐演变而来的。在进化的过程中,GPT系列模型的参数数量呈指数级增长,从初代GPT的1.17亿个参数,到GPT-2的15 亿个参数,再到 GPT-3的1750 亿个参数。模型越来越大,训练…

DDD领域分析

DDD领域分析是一种对现实业务进行建模分析的一种方法&#xff0c;它对业务问题做了分类&#xff0c;分层与抽象&#xff0c;为后面代码的编写理清了思路。 如何理解DDD呢&#xff1f;首先DDD中有许多名称&#xff0c;我这里一一列举出来&#xff1a;领域&#xff0c;子域&…

ES集群搭建(仅供自己参考)

单节点问题&#xff1a;单机的elasticsearch做数据存储&#xff0c;面临的两个问题&#xff1a;海量的数据存储问题、单节点故障。 一个节点存储的数据是有限的。 海量数据存储问题&#xff1a;将索引库从逻辑上拆分为N个分片&#xff08;shard&#xff09;&#xff0c;存储到…

【测试工具篇一】全网最强保姆级教程抓包工具Fiddler(2)

本文接上篇Fiddler介绍&#xff0c;开始讲fiddler如何使用之前&#xff0c;给大家讲讲http以及web方面的小知识&#xff0c;方便大家后面更好得理解fiddler使用。 目录 一、软件体系结构---B/S与C/S架构 B/S架构 C/S架构 二、HTTP基础知识 什么是http请求和响应? http协…