小结:
-
每个类都有且仅有一个原型对象
-
每个类可以有多个实例对象
-
实例对象(a)的__proto__属性指向该类(A)的原型对象,即:
a.__proto__ === A.prototype
-
自定义对象A的原型对象(A.prototype)是Object类的实例对象,结合第3条得出结论:A.prototype的__proto__属性指向该类(Object)的原型对象,即
A.prototype.__proto__ === Object.prototype
-
结合第3、4条,可得:
a.__proto__.__proto__ === Object.prototype
,这就是原型链 -
Object类是所有类的源头,所以
Object.prototype.__proto__ === null
-
而A、Object都是构造函数(类),即:A、Object都是函数对象,即A、Object都是Function类的实例对象,结合第3条得出结论:
A.__proto__ === Function.prototype
、Object.__proto__ === Function.prototype
-
而Function也是构造函数(类),即Function也是函数对象,即Function是Function类的实例对象,结合第3条得出结论:
Function.__proto__ === Function.prototype
-
Function跟A一样,它的原型对象是Object类的实例对象,即:
Function.prototype.__proto__ === Object.prototype
-
类中定义的属性都在实例对象上,定义的方法都在原型对象上。
详述:
在 JavaScript 中,prototype 和 proto 都与类的原型机制有关,但它们有不同的用途和含义。以下是对它们的详细解释:
prototype
- prototype 是函数对象的一个属性。每一个函数在创建时都会自动拥有一个 prototype 属性,这个属性是一个对象,包含了特定类型的对象实例共享的属性和方法。
- 当你使用构造函数创建一个对象时,这个对象的 proto 属性会指向构造函数的 prototype 属性。
- prototype 属性主要用于实现基于原型的继承。
示例
// 定义一个构造函数
function Person(name) {
this.name = name;
}
// 向构造函数的 prototype 属性添加方法
Person.prototype.greet = function() {
console.log('Hello, ' + this.name);
};
// 创建一个实例
const alice = new Person('Alice');
// 使用实例调用 prototype 方法
alice.greet(); // 输出:Hello, Alice
在这个示例中,Person.prototype 包含了所有实例共享的方法。当你创建一个新的 Person 实例时,这个实例会继承 Person.prototype 上的所有方法。
proto
- proto 是每一个 JavaScript 对象的内部属性。它指向该对象的构造函数的 prototype 属性,即该对象的原型。
- proto 是用来访问对象的原型的,是 JavaScript 中实现原型链的关键。
- 虽然可以直接访问和修改 proto 属性,但不推荐这样做,因为这会影响性能和代码的可维护性。更推荐使用 Object.getPrototypeOf 和 Object.setPrototypeOf 方法。
示例
// 创建一个对象
const obj = {};
// obj 的原型是 Object.prototype
console.log(obj.__proto__ === Object.prototype); // 输出:true
// 创建一个构造函数
function Animal() {}
// 创建一个实例
const dog = new Animal();
// dog 的原型是 Animal.prototype
console.log(dog.__proto__ === Animal.prototype); // 输出:true