Javascript高级程序设计 第4版 第4章

131 阅读2分钟

第 4 章 变量、作用域与内存

通过变量使用原始值与引用值

理解执行上下文

理解垃圾回收

4.1 原始值与引用值

JavaScript 变量是松散类型。

变量不过是特定时间点一个特定值的名称而已。

ECMAScript 变量包含两种不同类型的数据:原始值和引用值

类别原始值引用值
定义最简单的数据(Undefined,Null,Boolean,String和Symbol)由多个值构成的对象(Object)
访问方式按值访问(by value)按引用访问(by reference)
操作对象存储在变量中的实际值对该对象的引用(reference)

4.1.1 动态属性

定义的变量是否有动态属性:

引用值:可以随时添加、修改和删除其属性和方法。但原始值不可以。

// 引用值
let person = new Object();
person.name = 'Nicholas';
console.log(person.name); // "Nicholas"

// 原始值
let name = 'Nicholas';
name.age = 27;
console.log(name.age); // "undefined"

注意:原始类型的初始化可以只使用原始字面量形式。如果使用的是 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

4.1.2 复制值

除了存储方式不同,原始值和引用值在通过变量复制时也有所不同。

// 原始值复制方式
let num1 = 5;
let num2 = num1;

其复制过程如下:

4-1.jpg

可以看到,这两个变量可以独立使用,互不干扰。

// 引用值复制方式
let obj1 = new Object();
let obj2 = obj1;
obj1.name = 'Nicholas'; // 修改 obj1 的属性
console.log(obj2.name); // "Nicholas"

4-2.jpg 在把引用值从一个变量赋给另一个变量时,存储在变量中的值会被复制到新变量所在的位置。区别在于,这里复制的值实际上是一个指针,它指向存储在堆内存中的对象。操作完成后,两个变量实际上指向同一个对象。

4.1.3 传递参数

4.1.4 确定类型

4.2 执行上下文与作用域

4.2.1 作用域链增强

4.2.2 变量声明

4.3 垃圾回收

4.3.1 标记清理

4.3.2 引用计数

4.3.3 性能

4.3.4 内存管理

4.4 小结