卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章64334本站已运行4115

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 = 26console.log(name.age)   // undefined

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

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

let name1 = '何小生'let name2 = new String('小何')
name1.age = 26name2.age = 27console.log(name1.age)    // undefinedconsole.log(name2.age)    // 27console.log(typeof name1) // stringconsole.log(typeof name2) // object

激活值

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

let num1 = 5const 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也可以出访这个属性,因为它们都指向同一个对象。

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

卓越飞翔博客
上一篇: 记一次WordPress主题模板破解过程
下一篇: Python爬取知乎内容脚本

相关推荐

留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏