JavaScript 初学者必看“new”

作者:代码拾荒

时间:2026-10-22

浏览:576

本文深入解析 JavaScript 中 new 运算符的执行流程,包括创建空对象、绑定 this、链接 __proto__ 及返回实例。通过构造函数示例,阐明原型链机制如何优化内存与计算资源,并展示如何在原型上添加共享方法以实现高效继承。

文章目录

译者按:本文简要介绍 new 运算符,重点阐述原型(prototype)机制,推荐阅读。

原文标题:JavaScript For Beginners: the ‘new' operator

译者:Fundebug

为确保证可读性,本文采用意译方式。版权归原作者所有,翻译仅供学习使用。

new 运算符的执行流程

使用 new 关键字时,会执行以下操作:

1. 创建一个全新的空对象; 2. 将 this 关键字绑定至该对象; 3. 为该对象添加名为 __proto__ 的属性,使其指向构造函数的 prototype 属性; 4. 返回该 this 对象。

若上述概念尚不清晰,接下来将通过具体示例进行详细解析。首先定义一个名为 Student 的构造函数,该函数接收 name 和 age 两个参数。


function Student(name, age){
 this.name = name;
 this.age = age;
}

现在使用 new 关键字创建一个新对象:


var first = new Student('John', 26);

具体发生了什么?

1. 创建一个新的对象,暂命名为 obj; 2. 将 this 绑定至 obj,此后对 this 的任何引用均指向 obj; 3. 向 obj 对象添加 __proto__ 属性,obj.__proto__ 指向 Student.prototype; 4. 将该 obj 对象赋值给变量 first。

我们可以通过打印语句进行测试:


console.log(first.name);
// John
console.log(first.age);
// 26

接下来深入探讨 __proto__ 的相关机制。

理解原型(Prototype)

原型 (Prototype)

每个 JavaScript 对象均拥有一个原型。所有对象均从其原型中继承属性和方法。

打开浏览器开发者控制台(Windows: Ctrl + Shift + J;Mac: Cmd + Option + J),输入之前定义的 Student 函数:


function Student(name, age) {
 this.name = name;
 this.age = age;
}

为了验证每个对象都拥有原型,输入:


Student.prototype;
// Object {...}

你将看到一个对象被返回。现在尝试定义一个新的对象:


var second = new Student('Jeff', 50);

根据前述解释,second 指向的对象应包含 __proto__ 属性,且该属性应指向父级的 prototype,我们来验证一下:


second.__proto__ === Student.prototype
// true

Student.prototype.constructor 指向 Student 构造函数,我们打印输出查看:


Student.prototype.constructor;
// function Student(name, age) {
// this.name = name;
// this.age = age;
// }

情况似乎愈发复杂,我们通过图示进行直观描述:

new 运算符的执行流程

Student 构造函数拥有一个名为 .prototype 的属性,该属性又包含一个 .constructor 属性反向指向 Student 构造函数,二者构成闭环。当我们使用 new 创建新对象时,每个对象的 __proto__ 属性均反向指向 Student.prototype。

原型在继承与性能优化中的作用

这种设计对继承至关重要。因为原型对象被该构造函数创建的所有对象共享。当向原型对象添加函数和属性时,所有其他对象均可访问。

本文仅创建了两个 Student 对象,若创建 20,000 个,将属性和函数置于 prototype 而非每个对象中,将极大节省存储和计算资源。

请看以下示例:


Student.prototype.sayInfo = function(){
 console.log(this.name + ' is ' + this.age + ' years old');
}

我们为 Student 的原型添加了一个新函数 sayInfo,因此使用 Student 创建的所有学生对象均可访问该函数。


second.sayInfo();
// Jeff is 50 years old

创建一个新的学生对象,再次进行测试:


var third = new Student('Tracy', 15);
// 如果我们现在打印third, 虽然只会看到年龄和名字这两个属性,
// 仍然可以访问sayInfo函数。
third;
// Student {name: "Tracy", age: 15}
third.sayInfo();
// Tracy is 15 years old

在 JavaScript 中,首先检查当前对象是否拥有该属性;若无,则检查原型中是否存在。此规则持续生效,直至找到属性或到达顶层全局对象仍未找到而返回失败。

继承机制使得我们无需定义 toString() 函数即可直接使用。因为 toString() 函数内置于 Object 的原型中。我们创建的每个对象最终均指向 Object.prototype,因此可以调用 toString()。当然,我们也可以重写此函数:


var name = {
 toString: function(){
 console.log('Not a good idea');
 }
};
name.toString();
// Not a good idea

创建的 name 对象首先检查是否拥有 toString,若拥有则不再向原型中查找。

总结

这些概念或许繁多,但理解后,利用原型可编写出更高效的代码。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章