JavaScript中的常量:不只是‘const’那么简单!

职场小段子

在繁忙的CodeCity,每个程序员都在自己的工作站上耕耘着,而李浩,一个对代码有着近乎偏执追求的中级开发者,正在为一个看似简单的常量问题头疼。 "李浩,你又在纠结什么?"同事小王打趣地问。 "哎,我在想,我们用'const'声明了一个常量,但好像并不是那么'常量'。"李浩皱着眉头回答。 小王好奇地凑过来:"怎么说?" 李浩打开编辑器,敲了一段代码:"你看,我用'const'声明了一个对象和一个数组。"

javascript 复制代码
const MY_OBJ = { key: 'value' };
const MY_ARRAY = [1, 2, 3];

他继续说:"我以为这样就能保证它们不被修改,但你看下面的操作。"

javascript 复制代码
MY_OBJ.key = 'new value'; // 属性被修改了
MY_ARRAY.push(4); // 数组被修改了

小王一愣:"啊,这...这不是和我们公司的年度预算一样吗?说是固定不变,结果每次会议都能给你调整一下。" 李浩苦笑:"对啊,所以光用'const'是不够的。我们需要更强大的武器,比如Object.freeze()。" 他迅速修改了代码:

javascript 复制代码
const IMMUTABLE_OBJ = Object.freeze({ key: 'value' });
const IMMUTABLE_ARRAY = Object.freeze([1, 2, 3]);
IMMUTABLE_OBJ.key = 'attempted change'; // 无效
IMMUTABLE_ARRAY.push(4); // 无效,但不会报错,需要额外处理

李浩解释道:"现在,IMMUTABLE_OBJ和IMMUTABLE_ARRAY是真的'冻住'了,任何修改都不会生效。这就好比我们的代码库,有了严格的代码审查流程,不允许随意更改。" 小王点头:"那如果我想创建一个真正的常量类,该怎么办?" 李浩微笑:"这时候,我们可以用闭包来模拟私有变量,保证外部无法修改。" 他展示了一段代码:

javascript 复制代码
const ConstantClass = (function() {
  let _privateValue = 'I am private';
  return {
    getValue: function() {
      return _privateValue;
    }
  };
})();
console.log(ConstantClass.getValue()); // 'I am private'
// ConstantClass._privateValue 是无法访问的

小王眼睛一亮:"原来如此,这就是传说中的'封装'吧!" 李浩点头:"没错,常量的世界很深奥,不只是'const'那么简单。掌握了这些技巧,我们的代码才能真正做到'稳如老狗'。" 两人相视一笑,继续投入到代码的世界中,每一次键入,都是对常量深刻理解的体现。

一、基础使用:const关键字

自从ES6标准推出以来,const关键字已经成为定义常量的首选方式了。const声明的变量在赋值后,它的值就不能被重新赋值了。 代码:

javascript 复制代码
const PI = 3.14159; // 常量PI的值不能被改变

而且在实际开发中,使用const定义常量可以避免因意外修改导致的程序错误,提高代码的稳定性。

但是要注意引用类型里面的值是可以改变的:

ini 复制代码
const fruits = ['apple', 'banana']; // 引用类型常量

尽管 fruits 被声明为常量,但其内部元素仍可被修改:

Javascript 复制代码
fruits.push('cherry'); // 允许修改数组内的元素

二、对象属性的不可变性:Object.defineProperty

但是在JavaScript中,对象是引用类型,其属性值是可以被修改的。为了实现对象属性的不可变性,我们可以使用Object.defineProperty方法。 代码:

javascript 复制代码
let settings = {};
Object.defineProperty(settings, 'MAX_USERS', {
    value: 0,
    writable: false, // 属性值不可改
    configurable: false // 不能删除或重新定义此属性
});

通过这种方式,我们可以精确控制对象属性的不可变性,适用于需要对特定属性进行保护的场景。

当我们去修改MAX_USERS属性时,它并不能成功

js 复制代码
settings.MAX_USERS = 1
console.log(settings.MAX_USERS); // 0

依旧打印的是0

Object.defineProperty 不仅可以用来创建只读属性,还可以设置属性的枚举性和可配置性。例如:

Javascript 复制代码
let config = {};
Object.defineProperty(config, 'maxUsers', {
    value: 100,
    writable: false,
    enumerable: true, // 可以在for...in循环中枚举
    configurable: false
});

此外,Object.defineProperty 还可以用来创建 getter 和 setter,这在实现属性的计算或验证逻辑时非常有用。

三、冻结对象:Object.freeze

有时候,我们需要让整个对象成为不可变,包括其所有属性。这时,可以使用Object.freeze方法。该方法会阻止修改、添加或删除任何属性。 代码:

javascript 复制代码
const config = {
    apiKey: "abcdef12345"
};
Object.freeze(config); // config对象现在完全不可变

当我去修改apiKey 的值时

并不能成功

Object.freeze方法适用于配置对象、枚举等场景,确保数据在整个应用中的稳定性。

四、使用立即执行函数表达式(IIFE)和闭包保护常量

在ES6之前,JavaScript没有提供原生的常量定义方式。我们通常会利用立即执行函数和闭包来模拟常量行为。 代码:

javascript 复制代码
const CONSTANT = (function() {
    let value = 42;
    return {
        getValue: function() {
            return value;
        }
    };
})();
// 这里CONSTANT.value不存在,只能通过CONSTANT.getValue()访问值

通过这种方式,我们可以保护内部变量,使其在外部无法直接修改。这种方法在早期JavaScript代码中较为常见,如今虽然有了const关键字,但在某些特定场景下,仍具有一定的实用价值。

总结:

我们发现"const"不仅是简单的值锁定机制,它开启了一扇通往更深层次代码控制的大门。从基本的"const"声明,到利用"Object.defineProperty"和"Object.freeze"实现对象属性的不可变性,再到运用闭包和IIFE保护常量免受外界干扰,每一步都揭示了"const"背后的广阔天地。总结而言,"JavaScript常量:'const'是答案,问题是什么"引出了关于代码稳定性和数据保护的深刻讨论,教导我们如何在复杂的应用环境中构建不可动摇的基石,确保程序的健壮性和维护性。

相关推荐
敲代码的小吉米39 分钟前
前端上传el-upload、原生input本地文件pdf格式(纯前端预览本地文件不走后端接口)
前端·javascript·pdf·状态模式
da-peng-song1 小时前
ArcGIS Desktop使用入门(二)常用工具条——数据框工具(旋转视图)
开发语言·javascript·arcgis
低代码布道师2 小时前
第五部分:第一节 - Node.js 简介与环境:让 JavaScript 走进厨房
开发语言·javascript·node.js
满怀10153 小时前
【Vue 3全栈实战】从响应式原理到企业级架构设计
前端·javascript·vue.js·vue
伟笑3 小时前
elementUI 循环出来的表单,怎么做表单校验?
前端·javascript·elementui
确实菜,真的爱4 小时前
electron进程通信
前端·javascript·electron
魔术师ID5 小时前
vue 指令
前端·javascript·vue.js
Clown956 小时前
Go语言爬虫系列教程 实战项目JS逆向实现CSDN文章导出教程
javascript·爬虫·golang
星空寻流年6 小时前
css3基于伸缩盒模型生成一个小案例
javascript·css·css3
waterHBO8 小时前
直接从图片生成 html
前端·javascript·html