使用 TypeScript 构建:基于乐高的指南
TypeScript:从JavaScript到TypeScript的平滑过渡,就像升级你的乐高积木搭建过程!
“尽其所能,用其所有”——这是我奉行的座右铭之一。这句话也体现了成长型思维模式的一部分。我们大多数前端或JavaScript开发者,都已经开始或完全迁移到TypeScript了。但有些人可能仍然难以理解其概念,或者难以将思维方式从JavaScript转换到TypeScript的模式。为了解决这个问题,我们将使用我最喜欢的工具之一:乐高积木。让我们从这里开始:“将JavaScript想象成一套基础乐高积木,你可以自由搭建;而TypeScript则是同一套积木,但配有详细的说明书和质量控制检查。” 关于TypeScript的更深入探讨,可以参考这里、这里以及这段视频。本指南旨在展示每个JavaScript概念如何转换为TypeScript,并使用乐高类比来帮助你更容易理解这些概念。
变量作用域和提升:搭建房间
概念定义
变量作用域是指在程序中变量可访问和使用的上下文。主要有两种作用域:局部作用域和全局作用域。在任何函数外部声明的变量位于全局作用域,这意味着可以在代码的任何地方访问和修改它。另一方面,在函数内部声明的变量位于局部作用域,并且只能在该函数内访问。JavaScript使用var
、let
和const
关键字来声明变量,每个关键字对作用域的影响都不同。用let
和const
声明的变量是块作用域的,这意味着它们只能在最近的封闭块{}
内访问。相比之下,var
是函数作用域的,使其在其声明的整个函数中可用。清晰地理解变量作用域有助于避免变量名称冲突和JavaScript程序中意外的副作用等问题。
提升是指在代码执行(编译阶段)之前,变量和函数声明被移动到其包含作用域顶部的行为。这意味着可以在声明变量和函数之前使用它们。函数声明是完全提升的,允许即使在代码中定义之前也能调用它们。但是,使用var
声明的变量会被提升,但不会初始化其初始值,因此在赋值之前访问它们将导致undefined
。用let
和const
声明的变量也会被提升,但不会被初始化,如果在声明之前访问它们会导致ReferenceError
。理解提升有助于开发人员通过正确构造变量和函数声明来避免常见的陷阱。
乐高类比
将作用域想象成不同的乐高搭建房间:
- 全局作用域:所有搭建者都可以访问积木的共享客厅。
- 函数作用域:个人的搭建桌。
- 块作用域:搭建桌的特定区域。
JavaScript 实现
// 全局搭建房间 const globalBricks = "每个人都可以使用这些"; function buildSection() { // 个人搭建桌 var tableBricks = "仅供此搭建者使用"; if (true) { // 特定区域 let sectionBricks = "仅供此部分使用"; } }
TypeScript 演变
// 为我们的搭建房间添加类型安全 type BrickType = "regular" | "special" | "rare"; const globalBricks: BrickType = "regular"; function buildSection(): void { // TypeScript确保我们只使用有效的积木类型 const tableBricks: BrickType = "special"; if (true) { // TypeScript阻止在此块之外使用sectionBricks let sectionBricks: BrickType = "rare"; } } // 真实世界的例子:配置管理 interface AppConfig { readonly apiKey: string; environment: "dev" | "prod"; features: Set<string>; } const config: AppConfig = { apiKey: "secret", environment: "dev", features: new Set(["feature1", "feature2"]) };
函数和闭包:搭建说明书
概念定义
函数是旨在执行特定任务的可重用代码块。这增强了模块化和代码效率。它们可以使用function
关键字定义,后跟名称、括号()
和用大括号{}
括起来的代码块。参数可以在括号或大括号内传递到函数中,这些参数充当调用函数时提供的值的占位符。JavaScript还支持匿名函数(没有名称)和箭头函数(提供更简洁的语法)。函数可以使用return
语句返回值,或者执行不返回值的操作。此外,JavaScript中的函数是一等对象,这意味着它们可以赋值给变量、作为参数传递以及从其他函数返回,从而实现函数式编程模式。
闭包是一个强大的特性,它允许函数记住并访问其词法作用域,即使函数在该作用域之外执行也是如此。当在一个函数内部定义一个函数并引用外部函数中的变量时,可以创建闭包。即使外部函数执行完毕后,内部函数仍然可以访问这些变量。此功能对于数据封装和在事件处理程序或回调等环境中维护状态非常有用。闭包支持私有变量等模式,其中函数可以公开特定行为,同时隐藏实现细节。
乐高类比
- 函数就像搭建说明书。
- 参数就像所需的积木。
- 返回值就像已完成的结构。
- 闭包就像密封的搭建套件,其中包含一些永久包含的积木。
JavaScript 实现
function buildHouse(floors, color) { const foundation = "concrete"; return function addRoof(roofStyle) { return `${color} house with ${floors} floors and ${roofStyle} roof on ${foundation}`; }; }
TypeScript 演变
// 带有类型的基本函数 interface House { floors: number; color: string; roofStyle: string; foundation: string; } // 为我们的搭建者添加类型安全 function buildHouse( floors: number, color: string ): (roofStyle: string) => House { const foundation = "concrete"; return (roofStyle: string): House => ({ floors, color, roofStyle, foundation }); } // 真实世界的例子:组件工厂 interface ComponentProps { id: string; style?: React.CSSProperties; children?: React.ReactNode; } function createComponent<T extends ComponentProps>( baseProps: T ): (additionalProps: Partial<T>) => React.FC<T> { return (additionalProps) => { // 组件实现 return (props) => <div></div>; }; }
对象和原型:搭建技巧
概念定义
JavaScript中的对象是基本的数据结构,用作相关数据和功能的容器。它们由键值对组成,其中每个键(属性)都映射到一个值,该值可以是任何有效的JavaScript类型,包括函数(方法)。对象可以通过几种方式创建:
- 对象字面量:
const obj = {}
- 构造函数:
new Object()
Object.create()
方法
原型系统是JavaScript内置的继承机制。每个对象都与另一个对象(称为其原型)具有内部链接。当尝试访问对象上不存在的属性时,JavaScript会自动在其原型链中查找它。此对象链会一直持续到到达具有null
原型的对象,通常是Object.prototype
。理解原型对于以下方面至关重要:
- 实现继承
- 在实例之间共享方法
- 管理内存效率
- 建立对象层次结构
乐高类比
将对象和原型想象成这样:
- 对象就像带有自己独特积木和说明书的专用乐高套件。
- 原型就像多个套件可以参考的主模板。
- 继承就像拥有一个基本套件,更高级的套件可以以此为基础搭建。
- 属性就像每个套件中的特定积木。
- 方法就像每个套件中包含的特殊搭建技巧。
JavaScript 实现
// 全局搭建房间 const globalBricks = "每个人都可以使用这些"; function buildSection() { // 个人搭建桌 var tableBricks = "仅供此搭建者使用"; if (true) { // 特定区域 let sectionBricks = "仅供此部分使用"; } }
TypeScript 演变
// 为我们的搭建房间添加类型安全 type BrickType = "regular" | "special" | "rare"; const globalBricks: BrickType = "regular"; function buildSection(): void { // TypeScript确保我们只使用有效的积木类型 const tableBricks: BrickType = "special"; if (true) { // TypeScript阻止在此块之外使用sectionBricks let sectionBricks: BrickType = "rare"; } } // 真实世界的例子:配置管理 interface AppConfig { readonly apiKey: string; environment: "dev" | "prod"; features: Set<string>; } const config: AppConfig = { apiKey: "secret", environment: "dev", features: new Set(["feature1", "feature2"]) };
异步编程:搭建团队
概念定义
异步函数和编程
异步函数是JavaScript中一种特殊的函数类型,它提供了一种优雅的方式来处理异步操作。当用async
关键字声明时,这些函数会自动返回一个Promise,并在其主体中启用await
关键字的使用。await
运算符会暂停函数的执行,直到Promise被解决或拒绝,从而允许以更同步、更易读的风格编写异步代码。此语法有效地减少了回调的复杂性,并消除了对嵌套Promise链的需求。例如,在async function fetchData() { const response = await fetch(url); }
中,函数会在继续执行之前等待fetch
操作完成,使代码的行为更可预测,同时确保主线程保持不被阻塞。当处理相互依赖的多个异步操作时,此模式特别有用,因为它允许开发人员编写清楚地表达操作顺序的代码,而不会牺牲性能。
Promise
Promise表示一个可能现在可用、将来可用或永远不可用的值。它是一个具有三种可能状态的对象:等待中、已完成或已拒绝。它用于处理异步操作。Promise具有诸如.then()
、.catch()
和.finally()
等方法,用于根据结果链接操作。这使得它们成为嵌套回调的有力替代方案,提高了代码的可读性和错误处理能力。
乐高类比
- 异步函数就像团队成员在处理不同的部分。
- Promise就像交付已完成部分的协议。
JavaScript 实现
// 全局搭建房间 const globalBricks = "每个人都可以使用这些"; function buildSection() { // 个人搭建桌 var tableBricks = "仅供此搭建者使用"; if (true) { // 特定区域 let sectionBricks = "仅供此部分使用"; } }
TypeScript 演变
// 为我们的搭建房间添加类型安全 type BrickType = "regular" | "special" | "rare"; const globalBricks: BrickType = "regular"; function buildSection(): void { // TypeScript确保我们只使用有效的积木类型 const tableBricks: BrickType = "special"; if (true) { // TypeScript阻止在此块之外使用sectionBricks let sectionBricks: BrickType = "rare"; } } // 真实世界的例子:配置管理 interface AppConfig { readonly apiKey: string; environment: "dev" | "prod"; features: Set<string>; } const config: AppConfig = { apiKey: "secret", environment: "dev", features: new Set(["feature1", "feature2"]) };
现代特性:高级搭建技巧
概念定义
解构
这是一种将数组中的值或对象中的属性提取到不同的变量中的简洁方法。数组解构使用方括号[]
,而对象解构使用大括号{}
。此语法通过将值直接解包到变量中,减少了对重复代码的需求,从而更容易处理复杂的数据结构。例如,const [a, b] = [1, 2]
将1赋值给a,将2赋值给b,而const { name } = person
从person对象中提取name属性。
展开运算符
展开运算符由三个点(...)表示。它允许将诸如数组或对象之类的可迭代对象扩展到需要多个元素或键值对的地方。它可以用于复制、组合或将数组元素作为函数参数传递。例如,const arr = [1, 2, ...anotherArray]
。
可选链
可选链由?.
表示。它提供了一种安全的方式来访问深度嵌套的对象属性,而不会在属性未定义或为null时导致错误。如果引用为nullish,它会短路并立即返回undefined。例如,user?.address?.street
在访问street之前检查user和address是否存在。此语法可防止运行时错误,并使处理嵌套数据结构更加简洁和不易出错,尤其是在API或依赖于用户输入的数据中。
乐高类比
- 解构就像将积木分类到容器中。
- 展开运算符就像在套件之间复制积木。
- 可选链就像在使用积木之前检查积木是否存在。
JavaScript 实现
function buildHouse(floors, color) { const foundation = "concrete"; return function addRoof(roofStyle) { return `${color} house with ${floors} floors and ${roofStyle} roof on ${foundation}`; }; }
TypeScript 演变
// 带有类型的基本函数 interface House { floors: number; color: string; roofStyle: string; foundation: string; } // 为我们的搭建者添加类型安全 function buildHouse( floors: number, color: string ): (roofStyle: string) => House { const foundation = "concrete"; return (roofStyle: string): House => ({ floors, color, roofStyle, foundation }); } // 真实世界的例子:组件工厂 interface ComponentProps { id: string; style?: React.CSSProperties; children?: React.ReactNode; } function createComponent<T extends ComponentProps>( baseProps: T ): (additionalProps: Partial<T>) => React.FC<T> { return (additionalProps) => { // 组件实现 return (props) => <div></div>; }; }
总结
从JavaScript到TypeScript的过渡就像升级你的乐高搭建过程:
-
JavaScript(基础搭建):
- 自由形式的搭建
- 灵活的积木使用
- 运行时错误发现
-
TypeScript(专业搭建):
- 详细和具体的说明书
- 积木兼容性检查
- 建造前的错误预防
关键过渡技巧:
- 从基本类型注解开始。
- 逐渐添加接口和类型定义。
- 使用编译器尽早捕获错误。
- 尽可能利用类型推断。
- 逐渐添加严格的null检查和其他编译器选项。
记住:TypeScript是在你的JavaScript知识的基础上构建的,它增加了安全性和清晰度,而不是改变基本的搭建过程。也就是说,我的建议仍然是……先学习JavaScript,然后再学习TypeScript。
参考文献
- W3Schools. (n.d.). JavaScript scope. W3Schools. Retrieved January 12, 2025, from https://www.php.cn/link/84b184211c5d929d9435a371eb505cad
- Mozilla. (n.d.). Variables — JavaScript. MDN Web Docs. Retrieved January 14, 2025, from https://www.php.cn/link/646e69d6e105d351e4e31a2e02a69b0e
以上是使用 TypeScript 构建:基于乐高的指南的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务
