likes
comments
collection
share

JavaScript中的常量-除了’const‘你还知道几种?

作者站长头像
站长
· 阅读数 16

职场小段子

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

const MY_OBJ = { key: 'value' };
const MY_ARRAY = [1, 2, 3];

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

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

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

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是真的‘冻住’了,任何修改都不会生效。这就好比我们的代码库,有了严格的代码审查流程,不允许随意更改。” 小王点头:“那如果我想创建一个真正的常量类,该怎么办?” 李浩微笑:“这时候,我们可以用闭包来模拟私有变量,保证外部无法修改。” 他展示了一段代码:

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声明的变量在赋值后,它的值就不能被重新赋值了。 代码:

const PI = 3.14159; // 常量PI的值不能被改变

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

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

const fruits = ['apple', 'banana']; // 引用类型常量

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

fruits.push('cherry'); // 允许修改数组内的元素

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

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

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

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

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

settings.MAX_USERS = 1
console.log(settings.MAX_USERS); // 0

依旧打印的是0

JavaScript中的常量-除了’const‘你还知道几种?

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

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

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

三、冻结对象:Object.freeze

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

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

当我去修改apiKey 的值时

JavaScript中的常量-除了’const‘你还知道几种?

并不能成功

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

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

在ES6之前,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’是答案,问题是什么”引出了关于代码稳定性和数据保护的深刻讨论,教导我们如何在复杂的应用环境中构建不可动摇的基石,确保程序的健壮性和维护性。

转载自:https://juejin.cn/post/7390339205974638611
评论
请登录