请说下你对__proto__和prototype的理解
在 JavaScript 中,__proto__ 和 prototype 是两个容易混淆但又至关重要的概念,它们都与原型链相关,但扮演着不同的角色。理解它们的区别对于理解 JavaScript 的继承机制至关重要。
prototype (原型对象)
- 定义:
prototype属性是函数对象才拥有的属性。它指向一个对象,这个对象就是通过该函数创建的实例的原型。换句话说,当使用new运算符创建一个新的对象时,新对象的__proto__属性会指向构造函数的prototype属性。 - 作用:
prototype属性用于定义通过构造函数创建的对象的共享属性和方法。所有通过该构造函数创建的实例都共享同一个原型对象。这样可以节省内存,并且方便地实现继承。 - 例子:
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log("Hello, my name is " + this.name);
};
const person1 = new Person("Alice");
const person2 = new Person("Bob");
person1.greet(); // Output: Hello, my name is Alice
person2.greet(); // Output: Hello, my name is Bob
console.log(person1.greet === person2.greet); // Output: true (Both instances share the same greet function)
__proto__ (原型链指针)
- 定义:
__proto__属性是所有对象都拥有的属性 (除了通过Object.create(null)创建的对象)。它是一个内部属性,指向创建该对象的构造函数的prototype属性。换句话说,它指向该对象的原型。 - 作用:
__proto__属性构成了 JavaScript 的原型链。当访问一个对象的属性时,JavaScript 引擎首先会在对象自身查找该属性。如果找不到,就会沿着__proto__指向的原型对象继续查找,直到找到该属性或者到达原型链的顶端 (null)。 - 例子: 在上面的例子中,
person1.__proto__指向Person.prototype。
关键区别总结:
| 特性 | prototype |
__proto__ |
|---|---|---|
| 归属 | 函数对象 | 所有对象 (除Object.create(null)创建的对象) |
| 作用 | 定义实例的原型 | 指向对象的原型 |
| 访问方式 | 直接访问 | 通过 Object.getPrototypeOf(obj) 或非标准的 obj.__proto__ 访问 |
Object.getPrototypeOf()
推荐使用 Object.getPrototypeOf(obj) 来获取对象的原型,因为它比 __proto__ 更标准和更可靠。 __proto__ 虽然在大多数现代浏览器中都受支持,但它并不是 ECMAScript 标准的一部分,并且在某些环境中可能不可用。
最佳实践:
为了代码的可读性和可维护性,建议使用现代 JavaScript 的 class 语法来定义类和继承关系,它底层仍然是基于原型链的,但提供了更清晰的语法。
希望这个解释能够帮助你理解 __proto__ 和 prototype 的区别。
浙公网安备 33010602011771号