原型与原型链
大约 3 分钟
原型与原型链
原型和原型链是对象上的一个重要的特性,它们是 JavaScript 中实现继承和共享属性的基础,也是我们在学习对象的过程中一个非常重要的知识点。
下图是浏览器中对象的原型结构图:

原型
每个对象都有一个原型对象,可以通过__proto__
属性访问,当我们在读取对象上的某一个属性时,如果对象本身没有定义这个属性,那么就会从对象的原型对象上查找该属性,这种现象叫做 原型继承。
const fruit = {
smell:'sweet',
weight:function(){
return `${200}g`;
}
};
const apple= {
color:'red'
}
apple.__proto__ = fruit;
console.log(apple.smell); // 输出 'sweet'
console.log(apple.weight()) // 输出 '200g'
在上面的例子中,我们将 apple
对象的原型对象设置为 fruit
对象,所以它便继承了 smell
属性和 weight
方法。
proto 与 [[prototype]]
在上面图片与示例代码中,我们发现对象的原型对象是通过 __proto__
属性访问的,而在浏览器中却展示的是 [[prototype]]
,那么它们有什么区别呢?
__proto__
是一个已经弃用了的属性(虽然还有浏览器仍然支持访问这个属性),用于访问对象的原型对象(一般不推荐直接使用)。[[prototype]]
是一个标准属性,它存在于所有对象中,用于访问对象的原型对象。
在浏览器中,__proto__
属性是 [[prototype]]
的非标准别名,它们的作用完全相同。如果想要操作对象的原型对象,推荐以下方法:
- 使用
Object.getPrototypeOf(obj)
方法获取对象的原型对象。 - 使用
Object.setPrototypeOf(obj, newProto)
方法设置对象的原型对象。
原型链
原型链是一种由原型对象组成的链式结构,用于实现继承和共享属性。当访问一个对象的属性时,JavaScript 会首先在当前对象中查找,如果没有找到,则会沿着原型链向上查找,直到找到为止。
原型链的终点是 null
,表示原型链的结束。
原型链的用途
原型链是 JavaScript 中实现继承和共享属性的基础,它使得对象可以继承其他对象上的属性和方法。原型链的用途包括但不限于:
实现继承:通过原型链,子对象可以继承父对象的属性和方法。
const fruit = { smell:'sweet', weight:function(){ return `${200}g`; } }; const apple= { color:'red' } Object.setPrototypeOf(apple,fruit); console.log(apple.smell); // 输出 'sweet' console.log(apple.weight()) // 输出 '200g'
实现共享属性:通过原型链,多个对象可以共享同一个原型对象上的属性和方法。
const fruit = { smell:'sweet', weight:function(){ return `${200}g`; } }; const apple= { color:'red' } const banana= { color:'yellow' } Object.setPrototypeOf(apple,fruit); Object.setPrototypeOf(banana,fruit); console.log(apple.smell); // 输出 'sweet' console.log(banana.smell); // 输出 'sweet' console.log(apple.weight()) // 输出 '200g' console.log(banana.weight()) // 输出 '200g'
实现动态属性:通过原型链,可以在运行时为对象添加新的属性和方法。
const fruit = { smell:'sweet', weight:function(){ return `${200}g`; } }; const apple= { color:'red' } const banana= { color:'yellow' } Object.setPrototypeOf(apple,fruit); Object.setPrototypeOf(banana,fruit); fruit.price = 5; fruit.getColor = function(){ return this.color; } console.log(apple.smell); // 输出 'sweet' console.log(banana.smell); // 输出 'sweet' console.log(apple.getColor()); // 输出 'red' console.log(banana.getColor()); // 输出 'yellow' console.log(apple.price); // 输出 5 console.log(banana.price); // 输出 5