0

0

JavaScript类中实现不可变属性(final属性)的指南

心靈之曲

心靈之曲

发布时间:2025-11-18 14:40:02

|

706人浏览过

|

来源于php中文网

原创

JavaScript类中实现不可变属性(final属性)的指南

本文探讨了在javascript类中创建类似java“final”属性的方法,即定义不可重写或不可配置的类属性。通过利用`object.defineproperty`方法,开发者可以精确控制属性的`writable`和`configurable`特性,从而在类实例化后,阻止对特定属性值的修改或属性定义的变更,解决了传统`get`访问器可能带来的性能开销和逻辑复杂性问题,提供了一种更高效、更明确的属性控制机制。

理解JavaScript中的“不可变”属性需求

在许多面向对象编程语言中,例如Java,可以使用final关键字来声明一个属性,使其在初始化后不能被重新赋值。这种机制对于确保数据完整性和对象状态的稳定性至关重要。在JavaScript中,虽然我们有const关键字来声明不可变的变量,但将其直接应用于类实例的属性时,并没有一个等价的内建语法来声明一个在实例创建后就不能被修改的属性。

开发者有时会尝试使用get访问器来模拟这种行为,例如:

class MyClass {
  get someProperty() {
    // 每次访问都会重新计算或返回一个值
    return computeSomeValue(); 
  }
}

这种方法虽然可以阻止直接赋值,但存在一个潜在问题:如果computeSomeValue()是一个开销较大的操作,或者需要一个在实例生命周期内只计算一次并缓存的值,那么每次访问someProperty时都可能重复执行计算,导致性能下降。为了解决这个问题,通常需要引入额外的缓存逻辑,增加了代码的复杂性。

使用 Object.defineProperty 实现不可重写属性

JavaScript提供了一个强大的内建方法Object.defineProperty(),允许我们对对象的属性进行精细化控制。通过这个方法,我们可以定义或修改一个属性的特性,包括它的值(value)、是否可写(writable)、是否可枚举(enumerable)以及是否可配置(configurable)。

立即学习Java免费学习笔记(深入)”;

要创建一个类似“final”的属性,我们主要关注writable和configurable这两个特性。

1. 阻止属性值被重写 (writable: false)

将属性的writable特性设置为false可以阻止对该属性进行重新赋值。一旦属性被定义为不可写,任何尝试修改其值的操作都将失败(在严格模式下会抛出TypeError,在非严格模式下会静默失败)。

以下是在类中使用Object.defineProperty实现不可重写属性的两种常见方式:

方式一:先初始化后定义特性

CreateWise AI
CreateWise AI

为播客创作者设计的AI创作工具,AI自动去口癖、提交亮点和生成Show notes、标题等

下载

在这种方式下,我们首先像普通属性一样初始化它,然后在构造函数中通过Object.defineProperty来修改其特性。

class MyClass {
  // 属性首先被初始化
  someProperty = computeSomeValue(); 

  constructor() {
    // 在构造函数中定义属性特性,使其不可写、不可配置
    Object.defineProperty(this, "someProperty", {
      writable: false,    // 阻止重新赋值
      configurable: false // 阻止修改属性特性或删除属性
    });
  }
}

// 示例使用
function computeSomeValue() {
  console.log("计算 someProperty 的值...");
  return Math.random();
}

const instance = new MyClass();
console.log("初始值:", instance.someProperty); // 第一次访问时计算并获取值

try {
  instance.someProperty = "newValue"; // 尝试修改,会抛出错误
} catch (e) {
  console.error("尝试修改不可写属性时捕获到错误:", e.message);
}
console.log("修改后值:", instance.someProperty); // 值保持不变

方式二:在定义时直接设置特性和值

另一种方法是在构造函数中直接使用Object.defineProperty来定义属性,同时设置其初始值和特性。这种方式更简洁,因为它避免了先默认初始化再修改特性的步骤。

class MyClass {
  constructor() {
    // 在构造函数中直接定义属性,设置初始值并使其不可写、不可配置
    Object.defineProperty(this, "someProperty", {
      value: computeSomeValue(), // 直接设置属性的初始值
      writable: false,           // 阻止重新赋值
      configurable: false        // 阻止修改属性特性或删除属性
    });
  }
}

// 示例使用(同上)
function computeSomeValue() {
  console.log("计算 someProperty 的值...");
  return Math.random();
}

const instance = new MyClass();
console.log("初始值:", instance.someProperty);

try {
  instance.someProperty = "newValue";
} catch (e) {
  console.error("尝试修改不可写属性时捕获到错误:", e.message);
}
console.log("修改后值:", instance.someProperty);

这两种方式都有效地创建了一个在实例初始化后不能被重新赋值的属性。

2. 理解 configurable: false

除了writable: false之外,我们通常也会将configurable设置为false。

  • writable: false: 意味着属性的值不能被改变。
  • configurable: false: 意味着该属性的特性(包括writable、enumerable、value、get、set)不能再被修改,并且该属性不能从对象中删除。

将configurable设置为false,可以进一步增强属性的“最终性”,防止其被删除或其“不可写”状态被逆转。

注意事项与最佳实践

  1. 严格模式下的行为: 在严格模式下,尝试写入一个writable: false的属性会抛出TypeError。在非严格模式下,操作会静默失败,这可能导致难以调试的问题。因此,在现代JavaScript开发中,始终推荐使用严格模式。
  2. 性能考量: 与每次访问都执行函数体的get访问器不同,通过Object.defineProperty设置的value是固定的,访问时没有额外的计算开销,性能更优。
  3. 对象冻结: 如果你需要让整个对象的所有属性都不可变,可以考虑使用Object.freeze()方法。它会使对象变得不可扩展,并将其所有自身属性的writable和configurable特性设置为false。但这与只针对特定属性的控制有所不同。
  4. 继承: Object.defineProperty操作是针对实例自身的属性。如果子类需要覆盖或修改父类中定义的“final”属性,这通常是不允许的,因为父类的实例属性是不可配置的。

总结

在JavaScript类中实现类似Java“final”属性的需求,可以通过Object.defineProperty方法来优雅且高效地解决。通过将属性的writable和configurable特性设置为false,我们可以确保属性在初始化后其值不能被修改,并且其定义也不能被改变或删除。这种方法比使用简单的get访问器更具性能优势和明确的控制力,是管理类实例属性不变性的推荐实践。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
go语言 面向对象
go语言 面向对象

本专题整合了go语言面向对象相关内容,阅读专题下面的文章了解更多详细内容。

58

2025.09.05

java面向对象
java面向对象

本专题整合了java面向对象相关内容,阅读专题下面的文章了解更多详细内容。

63

2025.11.27

go语言 面向对象
go语言 面向对象

本专题整合了go语言面向对象相关内容,阅读专题下面的文章了解更多详细内容。

58

2025.09.05

java面向对象
java面向对象

本专题整合了java面向对象相关内容,阅读专题下面的文章了解更多详细内容。

63

2025.11.27

go语言 面向对象
go语言 面向对象

本专题整合了go语言面向对象相关内容,阅读专题下面的文章了解更多详细内容。

58

2025.09.05

java面向对象
java面向对象

本专题整合了java面向对象相关内容,阅读专题下面的文章了解更多详细内容。

63

2025.11.27

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

564

2023.09.20

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

25

2026.03.13

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

44

2026.03.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 6万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 3.4万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号