Javascript中__proto__和prototype的区别与联系。

662 阅读2分钟

首先定义 __proto__prototype

关于 __proto__

每个对象内部都有一个 [[prototype]] 属性,指向该对象继承的原型

从ECMAScript6开始,可以通过 Object.getPrototype()Object.setPrototype() 访问器来访问。

在这之前,大部分浏览器实现了非Javascript标准的 __proto__属性来访问 [[prototype]]

__proto__是一个访问器属性(一个getter函数和一个setter函数),可以用过它访问对象内部的[[prototype]]

现在推荐使用的是 Object.getPrototype()Object.setPrototype() , __proto__ 在ECMAScript标准中不推荐使用

再说说 prototype 属性

只有函数含有 prototype 属性,他代表该函数的原型对象(不是它继承的原型)

每个对象都含有 __proto__ 属性,他指向该对象继承的原型对象


JavaScript继承模型图解

这是一张网上很流行的图解

一眼看过去是很乱,没有头绪的看的话很难看懂。

我现在梳理了一下原型链主线


原型链主线

o1o2

o1o2 是通过 new Object() 生成的的对象

所以 o1.__proto__o2.__proto__ 指向 Object.prototype (o1o2 不是函数,没有prototype属性)

Object.prototype 是最顶级原型属性,基本上所有的对象的原型链最顶层都会继承到 Object.prototype, 除非你修改你的对象的继承,比如用 Object.create(null)

Object.prototype.__proto__ 等于 null 也就是说 Object.prototype 没有继承对象。

f1f2

f1f2 是通过 new Foo() 创建的对象

所以 f1.__proto__f2.__proto__ 指向 Foo.prototype (f1f2不是函数,没有prototype属性)

而每个Javascript函数都是一个 Function 创建的对象。

所以 Foo.__proto__ 指向 Function.prototype

Function.prototype 是一个对象,有 Object 创建

所以 Function.prototype.__proto__ 指向 Object.prototype

Function

上面说到每个Javascript函数都是一个 Function 创建的对象,函数是一种特殊的对象。

实际上每个函数的__proto__ 属性都指向 Function.prototype, 包括 FunctionObject 对象

Function.prototype.__proto__ 指向 Object.prototype

继承顺序

是不是很绕

现在重新走一遍继承顺序。

f1.__proto__ === Foo.prototype
Foo.prototype.__proto__ === Object.prototype
Object.prototype.__proto__ === null
o1.__proto__ === Object.prototype
Foo.__proto__ === Function.prototype
Function.prototype.__proto__ === Object.prototype
Function.__proto__ === Function.prototype
Object.__proto__ === Function.prototype

参考文档

继承与原型链

Object.prototype.proto