在JavaScript中,每个对象都有一个原型(prototype),原型是一个对象,它包含共享属性和方法的对象。JavaScript使用原型链(prototype chain)来实现对象之间的继承关系。
区别如下:
1. 原型(prototype):
原型是每个对象都具有的属性,它指向另一个对象,用于共享属性和方法。每个对象都有一个原型,通过__proto__
属性访问。
2. 原型链(prototype chain):
原型链是一种对象之间的连接方式,它由每个对象的原型构成。当访问一个对象的属性或方法时,如果对象本身没有该属性或方法,JavaScript会沿着原型链向上查找,直到找到或者到达原型链的顶端(通常是Object.prototype)。这样就实现了对象之间的属性和方法继承。
简而言之,原型是对象自身具有的属性,用于共享属性和方法。原型链是对象之间通过原型连接起来的链式结构,用于属性和方法的继承。
举个例子来说明:
// 定义一个对象const person = {name: 'John',age: 30,}// person 对象的原型是 Object.prototypeconsole.log(person.__proto__ === Object.prototype) // true// Object.prototype 的原型是 nullconsole.log(Object.prototype.__proto__ === null) // true
在上述例子中,person
对象的原型是Object.prototype
,而Object.prototype
的原型是null
。当我们访问person
对象的属性时,如果该属性不存在于person
对象本身,JavaScript会通过原型链查找,最终在Object.prototype
中找到。
总结起来,原型(prototype)是对象自身具有的属性,用于共享属性和方法;原型链(prototype chain)是对象之间通过原型连接起来的链式结构,用于属性和方法的继承。
__proto__
和prototype
是JavaScript中的两个不同的概念,它们有着不同的作用和用法。
__proto__
(双下划线proto)是每个对象都具有的内部属性,用于访问该对象的原型(prototype)。它是一个非标准的属性,但被现代浏览器广泛支持。- 通过
obj.__proto__
可以访问对象的原型。 __proto__
提供了一种从对象到原型的直接链接。
例如:
const obj = {};console.log(obj.__proto__); // 输出: {}
在使用ES6之前,
__proto__
是访问和设置对象原型的主要方式。然而,它已经被Object.getPrototypeOf()
和Object.setPrototypeOf()
方法所取代,推荐使用这些方法来操作对象的原型。- 通过
prototype
是函数对象(构造函数)特有的属性。它是一个指向原型对象的属性,用于定义构造函数创建的对象的共享属性和方法。原型对象是构造函数通过new
关键字创建的实例对象的原型。prototype
是函数对象的一个属性,用于定义构造函数的原型对象。- 通过构造函数创建的实例对象通过
__proto__
属性链接到构造函数的prototype
属性所指向的原型对象。
例如:
function Person() {}console.log(Person.prototype); // 输出:Person {}const person = new Person();console.log(person.__proto__); // 输出:Person {}
prototype
属性用于在构造函数中定义方法和属性,这些方法和属性可以被通过该构造函数创建的实例对象所共享。
总结起来:
__proto__
是每个对象都具有的内部属性,用于访问该对象的原型。prototype
是函数对象特有的属性,用于定义构造函数创建的对象的共享属性和方法。
请注意,虽然在现代JavaScript中__proto__
和prototype
仍然存在,但由于历史遗留原因和不规范的使用,推荐使用更标准的方法来操作对象的原型,如Object.getPrototypeOf()
,Object.setPrototypeOf()
和Object.create()
。