【proto和prototype区别】在JavaScript中,`__proto__` 和 `prototype` 是两个容易混淆的概念,虽然它们都与对象的原型链有关,但它们的用途和作用却大不相同。理解这两者之间的区别,对于深入掌握JavaScript面向对象编程至关重要。
一、基本概念
1. `prototype`
`prototype` 是一个函数(构造函数)的属性。当使用函数作为构造函数来创建对象时,该函数会自动拥有一个 `prototype` 属性。这个属性指向一个对象,而所有通过该构造函数创建的实例都会共享这个对象中的属性和方法。
例如:
```javascript
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log("Hello, " + this.name);
};
const person = new Person("Alice");
person.sayHello(); // 输出:Hello, Alice
```
在这个例子中,`Person.prototype` 是一个对象,它包含了一个 `sayHello` 方法。通过 `new Person(...)` 创建的实例 `person` 都可以访问到这个方法,因为它们的原型链最终指向了 `Person.prototype`。
2. `__proto__`
`__proto__` 是每个对象都有的一个内部属性,用来指向该对象的原型对象。它并不是标准的ECMAScript属性,而是浏览器厂商为了方便调试而引入的一个非标准属性。在现代JavaScript中,推荐使用 `Object.getPrototypeOf()` 来获取对象的原型。
例如:
```javascript
const obj = {};
console.log(obj.__proto__); // 指向 Object.prototype
```
`__proto__` 实际上是对象的原型链上的一个指针,它帮助JavaScript引擎在查找对象属性时进行链式查找。
二、关键区别
| 特性 | `prototype` | `__proto__` |
| 所属对象 | 仅存在于函数(构造函数)身上 | 存在于所有对象身上 |
| 作用 | 用于定义构造函数所创建实例的公共属性和方法 | 用于指向当前对象的原型对象 |
| 是否标准 | 标准属性(ECMAScript) | 非标准属性(浏览器实现) |
| 使用方式 | 通过构造函数访问 | 通过对象直接访问 |
三、实际应用中的区别
- `prototype` 是构造函数的属性,当你创建一个对象时,该对象的 `__proto__` 会指向构造函数的 `prototype`。
```javascript
function Foo() {}
const foo = new Foo();
console.log(foo.__proto__ === Foo.prototype); // true
```
- `__proto__` 是对象的属性,它反映了对象的继承关系。因此,它在原型链查找中起着重要作用。
四、总结
虽然 `__proto__` 和 `prototype` 都与对象的原型相关,但它们的作用和使用场景完全不同:
- `prototype` 是构造函数的属性,用于为所有实例提供共享的方法和属性;
- `__proto__` 是对象的内部属性,用于指向其原型对象,帮助实现原型链查找。
理解这两个概念的区别,有助于更清晰地把握JavaScript的原型机制,避免在开发过程中出现误解或错误。


