ts如何使用class类?与js的class类有什么区别?

本文介绍了 TypeScript 中的类(class)概念,包括对象(object)、面向对象的三大特性(封装、继承、多态),并展示了如何定义和使用类。强调了 TypeScript 特有的修饰符如 public、private、protected 和 static 的作用。private 属性限制了外部访问,protected 允许子类访问,而 static 关键字用于创建静态属性和方法。此外,还讨论了 readonly 关键字用于创建只读属性。文章通过实例展示了如何在 TypeScript 中应用这些概念。

类的简介

类(class): 定义了一切事物的抽象特点(属性和方法)
对象(object): 类的实例(通过 new 来生成)
面向对象特点: 封装,继承,多态

  • 封装: 将操作数据的细节隐藏起来,只暴露接口, 调用者只需要通过接口来访问对象
  • 继承: 子类继承父类, 子类除了拥有父类的特性外还可以拥有更加具体的特性
  • 多态: 同一个方法可以有不同的响应(猫和狗都继承自动物类,但是他们叫声各有不同)

在ts中如何使用class类呢?

定义

class 类名 { }

使用

const 形参 = new 类名(传参)

class Fn {
	name: string = '你吃饭了吗?'
}
const fn = new Fn
console.log(fn.name)

在这里插入图片描述

我这里使用的是 Code Runner这个插件,可以直接执行当前文件
在这里插入图片描述


ts的class类和js的class类有什么区别吗?

ts的特有属性:修饰符

public 公开的

默认公共 public 自由访问程序里定义的变量和方法
在这里插入图片描述

private 私有的

私有的 private 当成员被标记为私有属性,只能在类进行使用,不能外部使用,子类也不可访问

在这里插入图片描述


这边继承也是无法使用的
在这里插入图片描述


使用方式
在这里插入图片描述


protected 受到保护的

受保护的 protected private相似,唯一不同的是,被protected修饰的属性可以在子类中访问
在这里插入图片描述

static 静态的

当类中的方法被声明 为 static 时,其 实例化对象,不可调用该方法,只有类本身 ,以及其子类可以调用。


这里使用实例化打印Fn这个类的时候,会发现定义static的属性已经消失了
在这里插入图片描述


如何获取静态属性呢?
在这里插入图片描述

readonly 只读的

readonly人们常常与const相比,使当前的实例属性是只读的,不可以修改


如何修改实例属性呢?

在这里插入图片描述


修改静态属性
在这里插入图片描述


如何获取readonly的属性
在这里插入图片描述
当你要修改只读属性的时候在这里插入图片描述

小锦囊

staticreadonly 是可以一起使用的.
在这里插入图片描述


但是 划重点了啊
static 必须在前面,因为static决定了你的访问方式,默认是实例化属性,但是是需要先将实例化属性改为静态属性才能继续获取到里面的参数
在这里插入图片描述

<think>我们正在讨论TypeScript中两种不同的私有方法声明方式:`#getValues`(使用私有字段语法)和`private getValues`(使用访问修饰符)。这两种方式在实现私有性上有本质区别。 ### 一、核心区别概述 | 特性 | `#getValues` (硬私有) | `private getValues` (软私有) | |--------------------------|-------------------------------|-------------------------------| | **编译时检查** | ✅ 语法错误 | ✅ 编译错误 | | **运行时保护** | ✅ 完全无法访问 | ❌ 可通过反射突破 | | **继承访问** | ❌ 子不可访问 | ❌ 子不可访问 | | **型兼容性影响** | ❌ 不影响型结构 | ✅ 影响型结构(编译时移除) | ### 二、详细机制解析 #### 1. `#getValues` - ECMAScript标准私有方法 - **本质**:使用JavaScript原生私有字段语法(ES2022+) - **编译结果**: ```javascript class MyClass { #getValues() { /* ... */ } } ``` 编译为ES5时通过`WeakMap`模拟私有性: ```javascript var _getValues = new WeakMap(); class MyClass { constructor() { _getValues.set(this, function() { /* ... */ }); } } ``` - **运行时行为**: - 外部访问`instance.#getValues`直接抛出`SyntaxError` - 无法通过`Object.getOwnPropertyNames`获取 #### 2. `private getValues` - TypeScript访问修饰符 - **本质**:编译阶段的型检查约束 - **编译结果**: ```typescript class MyClass { private getValues() { /* ... */ } } ``` 编译为ES5后移除`private`标记: ```javascript class MyClass { getValues() { /* ... */ } // 变为公有方法! } ``` - **运行时行为**: - 外部仍可调用`instance.getValues()` - 仅依赖TS型检查阻止非法访问 ### 三、实际影响对比 #### 场景1:跨文件访问 ```typescript // FileA.ts class SecretVault { #realCode = 123; // 硬私有 private backup = 456; // 软私有 } // FileB.ts const vault = new SecretVault(); vault.#realCode; // ❌ 语法错误(即使忽略TS检查) vault.backup; // ❌ TS编译错误,但JS运行时可访问! ``` #### 场景2:使用纯JavaScript代码突破限制 ```javascript // 在JavaScript文件中 import { SecretVault } from './FileA'; const vault = new SecretVault(); vault.backup; // ✅ 实际可访问!(因为编译后private被移除) vault.#realCode; // ❌ 始终不可访问 ``` ### 四、设计选择建议 | 需求场景 | 推荐方案 | 原因 | |-------------------------|-------------------|-------------------------------| | 严格防止运行时访问 | `#getValues` | 确保即使脱离TS环境也不暴露 | | 需要兼容旧JS环境 | `private` | 硬私有语法需要ES2022+支持 | | 开发公共库 | `#getValues` | 避免私有方法被下游用户误用 | | 需要反射访问 | `private` | 硬私有完全无法反射访问 | ### 五、代码示例验证 #### TypeScript硬私有示例 ```typescript class EncryptionService { #key: string; // 硬私有字段 constructor(initialKey: string) { this.#key = initialKey; } #rotateKey() { // 硬私有方法 this.#key = this.#key.split('').reverse().join(''); } encrypt(data: string) { this.#rotateKey(); return Buffer.from(data).toString('base64'); } } // 测试访问 const service = new EncryptionService('secret'); service.encrypt('hello'); service.#key; // ❌ TS错误 + JS运行时错误 service.#rotateKey; // ❌ 同上 ``` #### TypeScript软私有示例 ```typescript class Database { private connectionString: string; constructor(conn: string) { this.connectionString = conn; } private connect() { console.log(`Connecting to ${this.connectionString}`); } } // 编译为JS后: /* class Database { constructor(conn) { this.connectionString = conn; } connect() { // 注意:private被移除! console.log(`Connecting to ${this.connectionString}`); } } */ // 在JavaScript中可突破访问 const db = new Database('mysql://root@localhost'); db.connect(); // ✅ 实际可调用! ``` ### 六、关键结论 1. **安全性优先级**:需要严格私有时选择`#fields`,如加密密钥处理[^1] 2. **运行时环境**:目标环境支持ES2022+时优先使用硬私有 3. **反射需求**:当需要保留反射访问可能性时使用`private` > 在大型TypeScript项目中,建议对核心安全模块使用硬私有(`#`),对普通业务模块使用`private`以保持灵活性[^2]。 §§相关问题§§ 1. TypeScript的`private`修饰符在编译后如何保证私有性? 2. 如何在继承体系中访问父的私有方法? 3. JavaScript的私有字段语法(`#`)有哪些浏览器兼容性问题? 4. TypeScript中能否同时使用`#`和`private`声明同一个方法? [^1]: 参见《TypeScript编程》第4章 - 对象 [^2]: TypeScript官方文档 [Classes - ECMAScript Private Fields](https://www.typescriptlang.org/docs/handbook/classes.html#ecmascript-private-fields)</think>### TypeScript 中 `#getValues`(硬私有) `private getValues`(软私有)的区别 #### 一、核心差异总结 | **特性** | `#getValues` (ECMAScript 私有字段) | `private getValues` (TypeScript 访问修饰符) | |------------------|-----------------------------------|--------------------------------------------| | **私有性强度** | ✅ 硬私有(运行时强制) | ❌ 软私有(仅编译时检查) | | **运行时保护** | ✅ 外部访问直接报错 | ❌ 编译后私有性消失 | | **编译后行为** | 通过 `WeakMap` 模拟私有性 | 直接移除 `private` 关键字 | | **反射可突破性** | ❌ 完全不可访问 | ✅ 可通过 JS 代码访问 | | **继承访问** | ❌ 子不可访问 | ❌ 子不可访问 | --- #### 二、技术原理详解 1. **`#getValues` - ECMAScript 标准私有方法** - **语法**:使用 `#` 前缀(ES2022 标准) - **编译结果**:通过 `WeakMap` 实现运行时私有性 ```javascript // TS 源码 class DataService { #getValues() { return [1, 2, 3] } } // 编译后的 JS 代码 var _getValues = new WeakMap(); class DataService { constructor() { _getValues.set(this, function() { return [1, 2, 3] }); } } ``` - **运行时行为**: ```typescript const service = new DataService(); service.#getValues(); // ❌ SyntaxError: Private field must be declared ``` 2. **`private getValues` - TypeScript 访问修饰符** - **语法**:使用 `private` 关键字 - **编译结果**:`private` 关键字被直接移除 ```javascript // TS 源码 class DataService { private getValues() { return [1, 2, 3] } } // 编译后的 JS 代码 class DataService { getValues() { return [1, 2, 3] } // 变为公有方法! } ``` - **运行时行为**: ```typescript const service = new DataService(); service.getValues(); // ✅ 实际可调用!(仅 TS 编译时报错) ``` --- #### 三、实际场景影响 1. **跨文件访问测试** ```typescript // FileA.ts class SecretVault { #secretKey = 123; // 硬私有 private backup = 456; // 软私有 } // FileB.ts const vault = new SecretVault(); vault.#secretKey; // ❌ 语法错误(即使忽略 TS 检查) vault.backup; // ❌ TS 编译错误,但 JS 运行时可访问! ``` 2. **使用纯 JavaScript 突破限制** ```html <!-- index.html --> <script> import { SecretVault } from './FileA.js'; const vault = new SecretVault(); console.log(vault.backup); // ✅ 输出 456 (私有性失效) </script> ``` --- #### 四、如何选择? | **场景** | **推荐方案** | **原因** | |------------------------------|------------------|----------------------------------| | 需要严格运行时保护(如加密逻辑) | `#getValues` | 确保即使脱离 TS 环境也不暴露 | | 需要兼容旧 JavaScript 环境 | `private` | 硬私有语法需要 ES2022+ 支持 | | 开发公共库 | `#getValues` | 避免下游用户意外访问内部方法 | | 需要反射访问内部方法 | `private` | 硬私有完全无法通过反射访问 | > 在安全敏感场景(如密钥管理),硬私有(`#`)是唯一可靠选择[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值