一、对象创建过程
a. 内存分配
- 当我们创建一个对象时(无论是通过构造函数还是字面量方式),JavaScript 引擎会在内存堆(Heap)中为这个对象分配空间。堆是一个用于存储复杂数据结构(如对象和数组)的区域。
// 创建对象并分配内存
var person = new Object();
person.name = 'Alice';
person.age = 30;
或
// 字面量方式创建对象并分配内存
var person = {
name: 'Alice',
age: 30
};
b. 构造函数调用
- 如果使用
new
关键字调用构造函数来创建对象,引擎会先创建一个新的空对象,然后将该对象的原型指向构造函数的prototype
属性,并将新对象作为上下文(this
)执行构造函数内部的代码。
function Person(name, age) {
this.name = name;
this.age = age;
}
var alice = new Person('Alice', 30);
二、执行过程
a. 属性访问与方法调用
- 在对象创建后,可以通过
.
或[]
操作符访问和修改其属性。 - 可以调用对象的方法进行相关操作。
alice.sayHello = function() {
console.log('Hello, my name is ' + this.name);
};
alice.sayHello(); // 输出:Hello, my name is Alice
b. 闭包与作用域链
- 函数内部可以访问外部作用域中的变量,这种特性形成了闭包。当函数被调用时,它会形成自己的执行上下文,其中包含了作用域链,作用域链用于在当前作用域以及所有父级作用域中查找变量。
function outerFunction() {
var outerVar = 'outer';
function innerFunction() {
console.log(outerVar); // 能够访问到outerVar,这是因为闭包的作用
}
innerFunction();
}
outerFunction();
三、释放过程
a. 垃圾回收机制
- JavaScript 采用了自动垃圾回收机制,主要是基于可达性分析算法。简单来说,如果一个对象不再有任何引用指向它,那么这个对象就是不可达的,会被垃圾回收器视为垃圾并最终清理掉其所占用的内存资源。
var obj1 = { data: 'some value' };
var obj2 = obj1;
obj1 = null; // 现在只有obj2指向原对象
// 后续如果obj2也被设置为null或者超出作用域,则原对象成为不可达,会被GC回收
b. 循环引用问题
- 当两个对象互相引用但没有其他引用指向它们时,尽管它们是不可达的,但由于互相引用导致垃圾回收器无法识别。现代浏览器和 Node. js 环境下的 V8 引擎已经实现了循环引用检测功能,但在某些情况下仍需注意避免造成循环引用。
总之,在 JavaScript 中,对象从创建到销毁的过程涉及内存管理、作用域规则以及垃圾回收策略等多个方面,理解这些概念对于编写高效且无内存泄漏的 JavaScript 代码至关重要。
目录