尽管有时感觉很久以前(睡眠不足时您往往会失去时间感),但我可以清楚地记得我在Operation Spark的第一天,Operation Spark是我即将完成的出色沉浸式程序,即将成为一名软件开发人员。 在第一天,我就被首次介绍了简单的计算机科学数据类型概念。
要了解“价值与参考”的概念,让我们快速回溯到第一天。 尽管Javascript是一种动态编程语言(因此不需要新变量直接与特定类型相关联),但是可以在Javascript中定义七个数据类型,并将它们分为两个主要类:Primitives和Complex。
基元是不可变的,这意味着它们不能被更改。 字符串,数字,布尔值,空值,未定义和符号都是原始类型。 另一方面,Object是唯一的Complex类型。 但是,在Javascript中有很多东西被认为是对象:数组,对象,函数。
现在,让我们深入研究这两类,以了解它们如何处理分配,复制和重新分配:
首先让我们看一下一些简单的原始值分配示例:

在这里,将创建字符串“网球”,数字4和布尔值false,并将其分配给变量mySport,doublePlayers和playVsFederer,就好像变量是框并将那些原始值放在这些框中一样。 但是,原始值具有固定的有限大小:最多8个字节的内存(那些是小盒子)。
因此,为了存储更大的值,复杂值开始起作用,因为它们可以是任意大小:在内存中创建一个复杂值(就像基元一样),但是分配给它的变量将引用该值而不是包含它。

购物清单可能很长,对吧? 因此,您可能会使用Array(复杂值)来存储该列表。

使用相同的示例,让我们看一下复制原始值和复杂值时会发生什么:

当将mySport分配给变量yourSport时,字符串’tennis’由Value复制,这意味着将创建一个实际的新字符串值’tennis’并将其分配给yourSport。
因此,当将mySport重新分配给“足球”时,它不会影响yourSport,后者仍然是“网球”。

另一方面,将myGroceryList分配给yourGroceryList时,将通过引用复制数组[‘cheese’,’bread’,’fruits’]。 不会创建新的数组-而是,变量yourGroceryList引用(或指向)与myGroceryList相同的现有Array。 假设我忘记了myGroceryList上的黄油,所以我添加了它。 突然,由于两个变量都引用同一唯一数组,因此yourGroceryList也包含黄油。
两种数据类型之间的另一个区别是何时比较变量:

尽管包含原始值的两个变量彼此相等,但是引用具有相同属性和值的对象的两个变量却不相等,因为它们是不同的实例/对象。

最后,在函数中传递变量时,基元和复杂值的行为也不同:

当将“ mysport”传递给“ changeSport”时,将在函数内部声明一个新的临时变量,其原始值与“ mySport”(网球)相同。 然后将该变量重新分配给“足球”,然后最终由“垃圾收集器”删除。 “ mySport”实际上没有任何变化,而“ mySport”仍然是“网球”。

另一方面,当将数组myGroceryList传递到changeGroceryList函数时,确实确实会临时创建一个新数组,但它指向与myGroceryList相同的数组。 因此,该函数实际上访问并更新了myGroceryList引用的数组—即使函数完成运行后,该函数内部的临时Array被垃圾回收,myGroceryList现在仍指向包含黄油而不是奶酪的数组。 作为法国人,我会想念我的奶酪的。
今天就这样。 我希望本文可以帮助您消除对基本概念的任何困惑,以使您继续学习Javascript的令人兴奋的旅程。 如果您有任何疑问,或者在美国有任何很棒的奶酪推荐,请随时在下面发表评论。