在 JavaScript 中,__proto__
和 prototype
都与对象的原型链有关,但它们的用途和含义有所不同。下面是对它们的详细解释和它们之间的关系:
__proto__
-
定义:
__proto__
是一个非标准的、旧的属性,用于访问或修改对象的原型。尽管在现代 JavaScript 中不推荐使用__proto__
,它仍然被广泛支持。
-
用途:
obj.__proto__
可以用来获取或设置对象obj
的原型。
-
示例:
const obj = {}; const proto = { a: 1 }; // 设置 obj 的原型为 proto obj.__proto__ = proto; console.log(obj.a); // 输出: 1
-
注意事项:
__proto__
是非标准的,不推荐使用。现代 JavaScript 应使用Object.getPrototypeOf()
和Object.setPrototypeOf()
来替代。
prototype
-
定义:
prototype
是构造函数对象的一个属性。它指向一个对象,该对象会作为新创建对象的原型。这是标准的 JavaScript 机制,用于实现继承和原型链。
-
用途:
- 当使用构造函数创建对象时,新对象的原型被设置为构造函数的
prototype
属性。
- 当使用构造函数创建对象时,新对象的原型被设置为构造函数的
-
示例:
function Person(name) { this.name = name; } Person.prototype.sayHello = function() { console.log(`Hello, my name is ${this.name}`); }; const alice = new Person('Alice'); alice.sayHello(); // 输出: Hello, my name is Alice
-
注意事项:
prototype
只能在构造函数中使用,并且它对所有由该构造函数创建的对象实例有效。
__proto__
和 prototype
的关系
-
创建关系:
- 当你使用构造函数创建一个对象时,
__proto__
属性被自动设置为构造函数的prototype
属性。例如:function Person(name) { this.name = name; } const alice = new Person('Alice'); console.log(alice.__proto__ === Person.prototype); // 输出: true
- 当你使用构造函数创建一个对象时,
-
访问和修改:
__proto__
用于访问和修改对象的原型链。它直接影响实例的原型,但不影响构造函数的prototype
属性。prototype
影响通过构造函数创建的所有实例的原型。例如,修改构造函数的prototype
会影响所有通过该构造函数创建的对象实例:function Person(name) { this.name = name; } Person.prototype.sayHello = function() { console.log(`Hello, my name is ${this.name}`); }; const alice = new Person('Alice'); Person.prototype.sayGoodbye = function() { console.log(`Goodbye, ${this.name}`); }; alice.sayGoodbye(); // 输出: Goodbye, Alice
-
__proto__
和prototype
的区别:__proto__
是每个实例都有的属性,指向它的原型。它是对象的内部属性。prototype
是构造函数的属性,定义了构造函数创建的所有对象实例的原型。
总结
__proto__
: 用于访问或设置对象的原型链上的一个链接,直接影响对象的原型。虽然在现代 JavaScript 中不推荐使用,但它在早期的实现中很常见。prototype
: 是构造函数的一个属性,定义了由该构造函数创建的所有对象实例的原型。它是标准的 JavaScript 机制,推荐使用Object.getPrototypeOf()
和Object.setPrototypeOf()
来操作对象的原型链。