本文首发于微信公众号:大迁世界, 我的微信:qq449245884,我会第一时间和你分享前端行业趋势,学习途径等等。
更多开源作品请看 GitHub https://github.com/qq449245884/xiaozhi ,包含一线大厂面试完整考点、资料以及我的系列文章。
快来免费体验ChatGpt plus版本的,我们出的钱
体验地址:https://chat.waixingyun.cn
可以加入网站底部技术群,一起找bug.
该文章讲解了 JavaScript 中 const 关键字的用法以及它的一些特性。该关键字用于创建常量,即一旦赋值之后就不能再修改。但是,使用 const 创建的对象和数组却可以被修改。本文通过讲解“赋值”和“变异”之间的重要区别,详细解释了这一现象。
文章首先介绍了变量的三种声明方式:var
、let
和 const
。它解释了这三种方式的区别,以及为什么使用 const
声明常量。然后,文章深入探讨了“赋值”和“变异”的区别,这是理解 const 的关键。虽然 const
创建的对象和数组。
正文开始
JavaScript 中的 const
关键字用于声明常量。常量通常被认为是“不能更改的变量”:
const hi = 5;
hi = 10;
// 🛑 Uncaught TypeError: Assignment to constant variable.
console.log(hi);
// -> 5
有趣的是,当我使用const创建一个对象时,我可以自由地更改它:
const person = {
name: 'Hassan',
};
person.name = 'Sujata';
// Seems to work?? 🤔
console.log(person);
// -> { name: 'Sujata' }
我怎么能够改变 person 变量?我使用了 const
!
为了理解这个表面上的矛盾,我们需要了解赋值和变异之间的区别。这是 JavaScript 中的核心概念,当您清楚地理解这个区别时,许多事情就会变得更加清晰。
变量名作为标签
下面是完全有效的JavaScript程序:
5;
这是另一个:
['apple', 'banana', 'cherry'];
在这两个例子中,我正在创建一些东西。一个数字和一个数组。当代码运行时,这些数据将被创建并存储在计算机的内存中。
这些程序并不是非常有用。我正在创建一些数据,但我没有访问它的方式!
变量允许我们在我们创建的东西上贴上标签,以便以后可以引用它。
// Create it now...
const fruits = ['apple', 'banana', 'cherry'];
// ...and access it later:
console.log(fruits);
// -> ['apple', 'banana', 'cherry']
当我刚开始学习编程时,我认为代码是从左到右执行的:首先我们创建一个 fruits 变量,就像一个空盒子,然后我们在这个盒子里组装我们的数组。
原来这并不是正确的心理模型。更准确的说法是,数组首先被创建,然后我们将我们的 fruits
标签指向它。
重新分配我们的标签
当我们使用 let
关键字创建一个变量时,我们能够更改该标签所引用的“事物”。
例如,我们可以将我们的 fruits
标签指向一个新值:
这被称为重新分配。实际上, fruits
标签应该指向一个完全不同的值:
// We start with a labeled array:
let fruits = ['apple', 'banana', 'cherry'];
// ⚠️⚠️⚠️⚠️
// 从上面的列表中选择其他选项
//查看它如何在代码中翻译!
我们没有修改数据,我们修改的是标签。我们将其从原始数组中分离出来,连接到一个新数组中。
相比之下,使用 const
创建的变量无法重新赋值:
这是 let
和 const
之间的根本区别。当我们使用 const
时,我们创建了一个不可摧毁的链接,将变量名和一段数据联系在一起。
然而,问题在于:我们仍然可以修改数据本身!只要标签保持完好无损。
例如,使用数组,我们可以轻松地添加/删除其中的项目。 fruits
变量仍然连接到同一个数组:
这被称为变异(mutation)。我们通过添加/删除项目来编辑数组的值。
这是另一个例子,使用对象而不是数组。只要标签继续指向相同的对象,我们就可以编辑对象中的键/值。
重新分配(将变量名称指向新事物)和突mutation (编辑事物内的数据)之间存在根本区别。
当我们使用 const
创建一个常量时,我们可以百分之百地确定该变量永远不会被重新分配,但是在变异方面没有任何承诺。 const
并不完全阻止变异。
这里还有一个问题:像字符串和数字这样的“原始”数据类型是不可变的。这使得事情变得更加混乱。我们将在下一节中讨论。
如果你正在寻找一种方法来确保你的数据不会被修改,那么有一个方法叫做Object.freeze()
,它可以派上用场。使用该方法可以将对象和数组冻结,使它们变成只读的,这样就可以保护它们免受修改。这是一种非常有用的方法,特别是在需要确保数据的不可变性时。使用这种方法,即使使用const
关键字也可以确保你的数据不会被修改
// With arrays:
const arr = Object.freeze([1, 2, 3]);
arr.push(4);
console.log(arr);
// -> [1, 2, 3]
// With objects:
const person = Object.freeze({ name: 'Hassan' });
person.name = 'Sujata';
console.log(person);
// -> { name: 'Hassan' }
据我所知,Object.freeze()
是防弹的。无法修改使用此方法冻结的对象/数组。
同样,如果你使用TypeScript,你也可以使用as const
断言来实现类似的结果
const arr = [1, 2, 3] as const;
arr.push(4);
// 🛑 Error: Property 'push' does not exist
// on type 'readonly [1, 2, 3]'.
与所有静态类型一样,当代码被编译为JavaScript时,这些保护就会消失,因此这并不能提供与Object.freeze()相同数量的保护。
原始数据类型
到目前为止,我们看到的所有示例都涉及对象和数组。但是如果我们有一个“原始”数据类型,例如字符串、数字或布尔值,该怎么办呢?
以一个数字为例:
let age = 36;
age = 37;
我们应该如何解释这个?我们是将 age
标签重新分配给一个新值,还是突变这个数字,将 36 编辑为 37
?
这就是问题所在:JavaScript 中的所有原始数据类型都是不可变的。无法“编辑”数字的值。我们只能将变量重新分配给不同的值。
假装有一个包含所有可能数字的大列表。我们已经将 age
变量分配给数字36
,但我们可以将它指向列表中的任何其他数字:
要明确的是,浏览器并没有所有可能数字的大索引。我希望在这里阐述的重点是数字本身无法更改。我们只能更改标签指向的数字。
这适用于所有原始值类型,包括字符串、布尔值、null等。
如上所述,在JavaScript中,原始值是不可变的;它们不能被编辑。但如果他们能做到呢?如果数字本身可以改变,那么语法会是什么样子呢?它看起来是这样的:
// 编辑数字36的值
36 = 37;
// 36这个数字不再存在了
console.log(36); // 37
所以,如果我们可以在JavaScript中改变原始值,那就意味着基本上覆盖某些数字,这样它们就永远不会再被引用了!这显然会让人感到困惑和无助,这就是为什么在JavaScript中基本类是不可变的。
编辑中可能存在的bug没法实时知道,事后为了解决这些bug,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。
交流
有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。
本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net