JavaScript海底两万里:[[Prototype]]、__proto__、prototype

争取一文帮自己搞清楚[[Prototype]]__proto__prototype的区别与联系。


在学习JavaScript原型相关内容时,包含”proto”的属性着实不少,各自都有不同的含义。

[[Prototype]]

[[Prototype]]对象的隐藏属性,可以认为是一个概念,表示该对象的原型。

proto

__proto__JavaScript提供的访问对象原型的方式,通过obj.__proto__可以访问到obj的原型,只不过现代JavaScript更加推荐使用Object.getPrototypeOf(obj)Object.setPrototypeOf(obj, [descriptors])来获取和设置对象obj的原型。

prototype

prototype是针对函数而言的,只有函数才有这个属性。比如F是一个构造函数,对于F.prototypeF.prototype = protoObj;表示**当创建了一个new F时,新对象的[[Prototype]]会被赋值为protoObj,也就是F.prototype**。

1
2
3
4
let protoObj = {};
function F() {}
F.prototype = protoObj;
let obj = new F(); // obj.__proto__ === F.prototype

简单来说,F.prototype就是调用构造函数F时创建的对象的原型,可以认为这个“原型”是对象的***模板,这与Java中类是对象的模板*的理念同样非常相似。

原型与原型继承

我们必须要区分这两个概念:构造方法的原型属性F.prototype是一个模板,它可以创建以此为参考的新对象;原型继承表示多个类之间的继承关系,通过__proto__可以读取和设置某个对象的[[Prototype]]属性,即设置该对象的父类。

一个例子

对于两个构造方法ParentChildChildParent继承,我们可以通过new Parent()new Child来创建两个对象parentchild

于是,我们可以得到以下推论:

  • child.__proto__ === parent === Parent.prototype

JavaScript海底两万里:[[Prototype]]、__proto__、prototype
https://skycurtain.github.io/2022/09/05/javascript-drowning-in-prototype-properties/
作者
Skycurtain
发布于
2022年9月5日
许可协议