javascript基础学习系列三十:变量、作用域与内存

JavaScript 中的变量可谓独树一帜。正如 ECMA-262 所规定的,JavaScript 变量是 松散类型的,而且变量不过就是特定时间点一个特定值的名称而已。

由于没有规则定义变量必须包含什 么数据类型,变量的值和数据类型在脚本生命期内可以改变。这样的变量很有意思,很强大,当然也有 不少问题。本章会剖析错综复杂的变量。

1. 原始值与引用值:

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

在把一个值赋给变量时,JavaScript 引擎必须确定这个值是原始值还是引用值。上一章讨论了 6 种 原始值:Undefined、Null、Boolean、Number、String 和 Symbol。保存原始值的变量是按值(by value)访问的,因为我们操作的就是存储在变量中的实际值。

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


2. 动态属性:

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

  let person = new Object();
   person.name = "Nicholas";
   console.log(person.name); // "Nicholas"

这个属性赋值了一个字符串"Nicholas"。在此之后,就可以访问这个新属性,直到 对象被销毁或属性被显式地删除。
原始值不能有属性,尽管尝试给原始值添加属性不会报错。比如:

let name = "Nicholas";
    name.age = 27;
    console.log(name.age);  // undefined

在此,代码想给字符串 name 定义一个 age 属性并给该属性赋值 27。紧接着在下一行,属性不见 了。记住,只有引用值可以动态添加后面可以使用的属性。
注意,原始类型的初始化可以只使用原始字面量形式。如果使用的是 new 关键字,则 JavaScript 会 创建一个 Object 类型的实例,但其行为类似原始值。下面来看看这两种初始化方式的差异:

   let name1 = "Nicholas";
    let name2 = new String("Matt");
    name1.age = 27;
    name2.age = 26;
    console.log(name1.age);    // undefined
    console.log(name2.age);    // 26
    console.log(typeof name1); // string
    console.log(typeof name2); // object

猜你喜欢

转载自blog.csdn.net/wanmeijuhao/article/details/135465088