返回

一文掌握原型和原型链中prototype、__proto__和constructor的区别

前端

JavaScript 中的原型、proto 和构造函数:揭开原型链的奥秘

在 JavaScript 中,理解原型和原型链至关重要,它们是对象继承和属性查找的基础。这三者密不可分,发挥着至关重要的作用:prototype__proto__constructor。本文将深入探讨它们的差异,帮助你更好地理解 JavaScript 中的原型和原型链。

什么是 prototype?

prototype 是一个指向另一个对象的指针,该对象包含了该对象的属性和方法。它是对象的原型,即它定义了对象的默认行为和属性。你可以通过 prototype 属性访问和修改对象的原型。

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

Person.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};

const person1 = new Person('John Doe', 30);

// 访问原型方法
person1.sayHello(); // 输出: Hello, my name is John Doe and I am 30 years old.

什么是 proto

__proto__ 属性也是一个指向对象的原型的指针。它的作用与 prototype 相同,但它是一个只读属性,不能直接修改对象的原型。在严格模式下,使用 __proto__ 访问对象的原型时,会抛出 TypeError 异常。因此,在严格模式下,推荐使用 prototype 属性来访问和修改对象的原型。

什么是 constructor?

constructor 属性指向对象的构造函数,该构造函数用于创建该对象。你可以通过 constructor 属性访问和修改对象的构造函数。

// Person 构造函数
function Person(name, age) {
  this.name = name;
  this.age = age;
}

const person1 = new Person('John Doe', 30);

// 访问构造函数
console.log(person1.constructor); // 输出: function Person(name, age) { ... }

prototype、proto 和 constructor 的区别

属性 作用 可修改性 严格模式
prototype 指向对象的原型 可修改 推荐使用
__proto__ 指向对象的原型 只读 抛出 TypeError 异常
constructor 指向对象的构造函数 可修改 可使用

原型和原型链

原型链是对象的原型指向的原型形成的链条。每个对象都有一个原型,原型又指向另一个原型,以此类推,直到到达 Object.prototype,它指向 null

const person1 = new Person('John Doe', 30);

// 原型链
person1.__proto__ === Person.prototype; // true
Person.prototype.__proto__ === Object.prototype; // true
Object.prototype.__proto__ === null; // true

结论

prototype__proto__constructor 都是 JavaScript 中与原型和原型链相关的关键属性。理解它们的差异对于理解对象继承和属性查找至关重要。在严格模式下,推荐使用 prototype 属性来访问和修改对象的原型。

常见问题解答

1. prototype 和 proto 有什么区别?

prototype 可以修改对象的原型,而 __proto__ 是只读的。在严格模式下,推荐使用 prototype 属性来访问和修改对象的原型。

2. constructor 的作用是什么?

constructor 属性指向对象的构造函数,该构造函数用于创建该对象。你可以通过 constructor 属性访问和修改对象的构造函数。

3. 原型链是什么?

原型链是对象的原型指向的原型形成的链条。每个对象都有一个原型,原型又指向另一个原型,以此类推,直到到达 Object.prototype,它指向 null

4. 为什么在严格模式下不能使用 proto

在严格模式下,使用 __proto__ 访问对象的原型时,会抛出 TypeError 异常。这是为了防止意外修改对象的原型。

5. 如何创建新的对象?

可以通过调用构造函数或使用 Object.create() 方法创建新的对象。