📅  最后修改于: 2023-12-03 15:37:04.814000             🧑  作者: Mango
在JavaScript中,原型(prototype)是一个关键概念。它是构造函数(constructor)创建的每个对象的基础,是实现继承的重要机制。而原型之间也存在一些差异,下面就给您详细介绍一下它们之间的区别。
每个通过构造函数创建的对象都有一个原型对象(prototype object)。可以通过构造函数的prototype
属性来访问原型对象。例如:
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log('Hello, my name is ' + this.name);
};
var john = new Person('John');
john.sayHello(); // 输出:Hello, my name is John
Person
构造函数定义了一个name
属性和一个sayHello
方法,并将sayHello
方法添加到构造函数的原型对象上。当我们创建了一个名为john
的Person
对象并调用它的sayHello
方法时,JavaScript会查找john
的原型对象来查找sayHello
方法。这种查找方式称为“原型链”。
除了构造函数原型外,每个对象实例也有自己的原型对象,它可以通过Object.getPrototypeOf()
方法访问。例如:
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log('Hello, my name is ' + this.name);
};
var john = new Person('John');
console.log(Object.getPrototypeOf(john) === Person.prototype); // 输出:true
在上面的代码中,我们使用Object.getPrototypeOf()
方法获取了john
的原型对象,然后将它与Person
构造函数的原型对象进行比较,结果为true
。
__proto__
属性在ES5之前,JavaScript没有标准的方法来访问对象实例的原型对象。为了解决这个问题,一些浏览器厂商添加了一个非标准的__proto__
属性,它允许开发者直接访问对象实例的原型对象。例如:
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log('Hello, my name is ' + this.name);
};
var john = new Person('John');
console.log(john.__proto__ === Person.prototype); // 输出:true
在上面的代码中,我们使用了john.__proto__
来访问john
的原型对象,然后将它与Person
构造函数的原型对象进行比较,结果为true
。
需要注意的是,在ES5中,__proto__
被标准化为一个访问原型对象的标准方法,即Object.getPrototypeOf()
。
在JavaScript中,由于每个对象都有一个原型,因此存在多个原型之间的区别。下面是一些主要的区别:
Object.prototype
是所有原型对象的根,它是直接创建的对象实例的原型,也是所有构造函数的默认原型。Object.prototype
。Object.setPrototypeOf()
方法或直接为__proto__
属性赋值来修改。但是,不推荐在生产代码中使用这些方法,因为它们是基于非标准的实现而来的,可能会导致不可预知的行为。以上是原型和原型之间的区别,它是JavaScript语言中非常重要的概念。掌握原型的概念和使用方法可以让我们更好地理解JavaScript的继承机制,并且提高我们代码的质量和性能。