「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」。
数据类型可能是一个令人难以置信的概念。但是作为程序员,我们每天都在使用数据类型——所以我们应该理解它们。
问题是,计算机如何存储这些数据类型?它不可能对每种数据类型都一视同仁。
在 JavaScript 中,数据类型分为两类,计算机以不同的方式对待每一类。我们有原始数据类型和引用数据类型。但这些是什么?为什么知道区别很重要?这就是我们将在本文中学习的内容。
JavaScript 中的原始数据类型
这些数据类型非常简单,有时被视为编程语言的最低实现级别。它们不是对象,也没有方法。
此类数据类型的示例包括数字、字符串、布尔值、null 和未定义。
但是你可能想知道字符串,因为它们确实有方法。事实上,JavaSvript 将原始字符串转换为字符串对象,因此可以使用字符串对象方法。
JavaScript 中如何处理原始数据类型?
当你在 JavaScript 中声明原始数据类型时,它存储在堆栈中。堆栈是计算机用来快速存储和检索数据的简单数据结构。
堆栈上的原始数据类型由您在程序中用于声明的变量名标识。对于你创建的每个原始数据类型,数据都会添加到堆栈中。
为了实现这一点,假设我们声明了一个变量 ,numOne并给它一个值 50。我们继续创建另一个变量 ,numTwo并为其分配相同的值 50。所以两个变量具有相同的值。
堆栈上发生的事情是,计算机为其分配的值创建空间numOne并将其存储在堆栈上。创建numTwo时,计算机再次创建空间,并将 50 存储在堆栈中。两个变量被赋予相同的值并不重要。
如果在编码过程中,我们决定更新numOne100 的值怎么办?这是否意味着numTwo也会改变?答案是不。
由于numOne和numTwo以不同方式存储在堆栈中,因此更新其中一个不会影响另一个。我们可以通过在我们的代码编辑器中实际尝试来进行试验。
记录numOne到控制台会输出 100,记录numTwo会输出 50。因此,实际上,这两个变量彼此没有关系。
let numOne = 50;
let numTwo = numOne; //numTwo=numOne=50
numOne = 100;
console.log(numOne); //outputs 100
console.log(numTwo); //outputs 50
既然我们已经看到处理原始数据类型是多么容易,那么让我们看看引用数据类型是如何工作的。
JavaScript 中的引用数据类型
与原始数据类型不同,引用数据类型本质上是动态的。也就是说,它们没有固定的大小。
它们中的大多数被视为对象,因此具有方法。此类数据类型的示例包括数组、函数、集合和所有其他类型的对象。
原始数据类型和引用数据类型有什么区别?
当计算机必须存储引用数据类型时,差异就出现了。当您创建一个变量并为其分配一个引用数据类型的值时,计算机不会直接将该数据类型存储在该变量中(与原始类型一样)。
您分配给该变量的是一个指针,该指针指向该数据类型在内存中的位置。令人困惑?我知道。
如上图所示,我们现在有两个数据结构。一个栈,一个堆。例如,假设我们声明了一个对象。对象本身存储在堆上,其指针存储在堆栈上。指针由对象的变量名标识,并指向该对象。
现在,我们可以创建一个变量 ,object1并为其分配一个对象。如果像以前一样,我们创建另一个变量object2,并将其分配给object1. 这是否意味着将在堆上创建另一个对象?答案是不。
由于对象已经存在于堆上,object2并且object1都指向同一个对象。
当我们更新object1. 如果我们将两个变量都记录到控制台,我们会看到更改影响了它们。这是因为它们指向堆上的同一个对象——更新一个变量当然会影响另一个变量。
let object1 = {
name:'Bingeh',
age:18
};
let object2 = object1;
//updating object1,
object1.age = 20;
console.log(object2); //we see that object2 also updates the age attribute
结论
现在你知道原始数据类型和引用数据类型之间的区别了。了解这些差异很重要——尤其是当你遇到像“空指针引用”这样的错误时——这样你就可以弄清楚它们发生的原因。