Const 和 Object.freeze()的区别

838 阅读2分钟

「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战

作者: Ashish Lahoti 译者:前端很美 来源:codingnconcepts

当我们在js中定义常量时,他们应该具备以下特点。

1.常量的值不能被修改
2.常量的引用不能被修改
一步一步实现这些特性。

使用let

先试着用let定义变量

let APP_NAME = "Coding N Concepts";

function getApplicationName() {
  APP_NAME = "Unkown App";
  return APP_NAME;
}

getApplicationName(); // Unkown App

在上面的例子中, 函数getApplicationName()改变了全局变量APP_NAME的值,我们怎么才能避免全局变量APP_NAME被改变呢?

使用 const

我们可以使用const 代替 let定义变量,从而防止变量的值被改变。

const APP_NAME = "Coding N Concepts";

function getApplicationName() {
  APP_NAME = "Unkown App"; // 这里会抛出TypeError异常
  return APP_NAME;
}

试图更改const定义的变量,将会抛出下面的错误

TypeError: Assignment to constant variable.”

再来看一个例子

const fruits = ['mango', 'apple'];
fruits.push('banana');
console.log(fruits); // ['mango', 'apple', 'banana']
const constants = {
  APP_NAME : "Coding N Concepts"
};
constants.APP_NAME = "Unknown App";
console.log(constants.APP_NAME); // "Unknown App"

我们可以看到,对于数组和对象, 即使你使用const定义, 你也可以修改它们的值。
const不会使变量的 不可变,而是使变量的绑定 不可变。 所有原始类型如integer,booleanstring通过值 绑定数据 arrayobject通过引用 绑定数据。 通过上面的例子,我们知道,虽然我不能改变objectarray的引用,但是我们可以改变他们的值。
但怎么才能使得objectarray的值也不能修改呢?

使用Object.freeze()

这正是Object.freeze()的应用场景,Object.freeze()忽略objectarray值的变化

let constants = Object.freeze({
  APP_NAME : "Coding N Concepts"
});

constants.APP_NAME = "Unknown App";

console.log(constants.APP_NAME); // "Coding N Concepts"

这个例子,我们可以看到修改值即不会报错,也不会生效。 Object.freeze()虽然不能修改object的值,但是却可以改变object的引用。

let constants = Object.freeze({
  APP_NAME : "Coding N Concepts"
});

constants = { 
  APP_NAME : "Unknown App"
};

console.log(constants.APP_NAME); // "Unknown App"

总结来说:

const不允许更改object的引用,却可以更改该值。

Object.freeze()不允许改变object的值,却允许改变object的引用。

它们组合在一起既可以防止objectarray的值改变, 也可以防止他们的引用的改变。

组合使用 const 和 Object.freeze()

const constants = Object.freeze({
  APP_NAME : "Coding N Concepts"
});

constants.APP_NAME = "Unknown App"; // 会被忽略

constants = { 
  APP_NAME : "Unknown App" 
}; // 会报错

上面的例子表明,组合使用constObject.freeze()对于定义Js中的常量是非常好用的。