ECMAScript变量 - 原始值和引用值

简介: ECMAScript变量 - 原始值和引用值

原始值和引用值


ECMAScript变量可以包含两种不同类型的数据:原始值和引用值。原始值(primitive value)就是最简单的数据,引用值(reference value)则是由多个值构成的对象。


在把一个值赋给变量时,JavaScript引擎必须确定这个值是原始值还是引用值。


原始值


Undefined,Null,Boolean,Number,String和Symbol。保存原始值的变量是按值(by value)访问的,因为我们操作的就是存储在变量中的实际值。


引用值


引用值是保存在内存中的对象。与其他语言不同,JavaScript不允许直接访问内存位置,因此也就不能直接操作对象所在的内存空间。在操作对象时,实际上操作的是该对象的引用(reference)而非实际的对象本身。为此,保存引用值的变量时按引用(by reference)访问的。


注意,在很多语言中,字符串是使用对象表示的,因此被认为是引用类型。ECMAScript打破了这个惯例。


动态属性


原始值和引用值的定义方式很类似,都是创建一个变量,然后给它赋一个值。不过,在变量保存了这个值之后,可以对这个值做什么,则大有不同。对于引用值而言,可以随时添加,修改和删除其属性和方法。比如,看下面的示例:


let person = new Object()
person.name = '何小生'
console.log(person.name)    // "何小生"
复制代码


这里,首先创建了一个对象,并把它保存在变量person中。然后,给这个对象添加了一个名为name的属性,并给这个属性赋值了一个字符串何小生.在此之后,就可以访问这个新属性,直到对象被销毁或属性被显式的删除。


原始值不能有属性,尽管尝试给原始值添加属性不会报错,例如:


let name = '何小生'
name.age = 26
console.log(name.age)   // undefined
复制代码


在此,代码想给字符串name定义一个age属性,并给该属性赋值26,紧接着在下一行,属性不见了。记住,只有引用值可以动态天价后面可以使用的属性。


注意,原始类型的初始化可以只使用原始字面量形式。如果使用的是new关键字,则JavaScript会创建一个Object类型的实际,但其行为类似原始值。下面来看看这两种初始化方式的差异:


let name1 = '何小生'
let name2 = new String('小何')
name1.age = 26
name2.age = 27
console.log(name1.age)    // undefined
console.log(name2.age)    // 27
console.log(typeof name1) // string
console.log(typeof name2) // object
复制代码


复制值


除了存储方式不同,原始值和引用值在通过变量复制时也有所不同。在通过变量把一个原始值赋值到另一个变量时,原始值会被复制到新变量的位置。请看下面的例子:


let num1 = 5
const num2 = num1
复制代码


这里,num1包含数值5。当把num2初始化为num1时,num2也会得到数值5。这个值跟存储在num1中的5是完全独立的,因为它是那个值的副本。


这两个变量可以独立使用,互不干扰。这个过程如图所示:


网络异常,图片无法展示
|


在把引用值从一个变量赋给另一个变量时,存储在变量中的值也会被复制到新变量所在的位置。区别在于,这里复制的值实际上是一个指针,它指向存储在堆内存中的对象。操作完成后,两个变量实际上指向同一个对象,因此一个对象上面的变化会在另一个对象上反应出来,如下面的例子所示:


let obj1 = new Object()
let obj2 = obj1
obj1.name = '何小生'
console.log(obj2.name)   // '何小生'      值已经被复制了
复制代码


在这个例子中,变量obj1保存了一个新对象的实例。然后,这个值被复制到obj2,此时两个变量都指向了同一个对象。在给obj1创建属性name并赋值后,通过obj2也可以访问这个属性,因为它们都指向同一个对象。


如图,展示了变量与堆内存中对象之间的关系


网络异常,图片无法展示
|

相关文章
|
3月前
|
存储 Java 程序员
对象的属性和值转换
对象的属性和值转换
36 0
|
存储 人工智能 JavaScript
JavaScript变量原始值与引用值
相比于其他语言,JavaScript 中的变量可谓独树一帜。正如 ECMA-262 所规定的,**JavaScript 变量是 松散类型的**,而且变量不过就是特定时间点一个特定值的名称而已。由于没有规则定义变量必须包含什 么数据类型,变量的值和数据类型在脚本生命期内可以改变。这样的变量很有意思,很强大,当然也有 不少问题。本章会剖析错综复杂的变量。
63 0
|
存储 JavaScript 前端开发
JavaScript中的原始值与引用值
原始值与引用值 在JavaScript中包含两种不同类型的数据:原始值和引用值 原始值 :是指不包含任何引用的值(简单值),比如数字、字符串、布尔值、null和undefined。 引用值 :是指包含了一个引用的值,比如对象、数组、函数和方法。
|
C语言 C++
不同类型的变量与零究竟是如何比较(1)
不同类型的变量与零究竟是如何比较
101 0
不同类型的变量与零究竟是如何比较(1)
|
存储 编译器
不同类型的变量与零究竟是如何比较(2)
不同类型的变量与零究竟是如何比较
116 0
不同类型的变量与零究竟是如何比较(2)
1、原始类型与引用类型(区别)
1、原始类型与引用类型(区别)
134 0
19、原始类型与引用类型
19、原始类型与引用类型
83 0
|
JavaScript
5、ES6的新特性(变量、常量、模板字符串、结构赋值)
5、ES6的新特性(变量、常量、模板字符串、结构赋值)
153 0