__proto__ 和 prototype的关系
先上答案:
对象上都有__proto__属性(函数也是对象)
一般情况下对象的__proto__属性指向该对象的构造函数的原型对象。
函数上才有prototype属性,该属性指向该函数的原型对象。
OK,下面来详细解释一下
什么是__proto__
这个其实是一个 internal slot (翻译成内置槽?),叫做 [[ prototype ]] ,也称为隐式原型。在js里所有的普通对象都会有。它的值要么是 null(原型链的最终), 要么还是一个对象。
之前并没有一个标准的方法来访问这个值,但是大多数浏览器都支持通过用.__proto__来得到它的值。所以 [[ prototype ]] 就被叫成了 __proto__ 。直到ES5中增加了标准的方法 :Object.getPrototypeOf()
All ordinary objects have an internal slot called [[Prototype]]. The value of this internal slot is either null or an object and is used for implementing inheritance.
什么是prototype
所有用 function 语句、函数字面量或者 Function 构造函数定义的函数都会同时自动创建一个 prototype 属性,指向该函数的原型对象。
另外,通过Function.prototype.bind()创建的函数没有 prototype 属性。
NOTE 1 Function objects created usingFunction.prototype.bind
are exotic objects. They also do not have aprototype
property.
这里 Function 的 prototype 有点不同,实际上它是内部对象%FunctionPrototype%,它本身是一个内置函数对象。
它有一些特殊的规则,比如 Function.prototype.length === 0 等
The Function prototype object is the intrinsic object %FunctionPrototype%. The Function prototype object is itself a built-in function object. When invoked, it accepts any arguments and returns undefined. It does not have a [[Construct]] internal method so it is not a constructor.NOTEThe Function prototype object is specified to be a function object to ensure compatibility with ECMAScript code that was created prior to the ECMAScript 2015 specification.
The value of the [[Prototype]] internal slot of the Function prototype object is the intrinsic object %ObjectPrototype% (19.1.3). The initial value of the [[Extensible]] internal slot of the Function prototype object is true.
The Function prototype object does not have a
prototype
property.The value of the
length
property of the Function prototype object is 0.The value of the
name
property of the Function prototype object is the empty String.
Object 的 prototype 也有一点不一样,它其实是内部对象%ObjectPrototype%,它本身是一个普通对象。
做为对象它的 __proto__ 也就是 [[prototype]] 值为 null 。
Object.prototype上挂载着valueOf,toString等方法。
The Object prototype object is the intrinsic object %ObjectPrototype%. The Object prototype object is an ordinary object.The value of the [[Prototype]] internal slot of the Object prototype object is null and the initial value of the [[Extensible]] internal slot is true.
两者的关系
先上一张神图 :
每个被构造函数创建出来的对象都有一个隐式引用,指向其构造函数的prototype属性的值。此外,一个原型可能对它的原型有一个非空的隐式引用,以此类推,就叫做原型链。
Every object created by a constructor has an implicit reference (called the object’s
prototype) to the value of its constructor’s
"prototype"
property. Furthermore, a prototype may have a non-null implicit reference to its prototype, and so on; this is called the
prototype chain. When a reference is made to a property in an object, that reference is to the property of that name in the first object in the prototype chain that contains a property of that name. In other words, first the object mentioned directly is examined for such a property; if that object contains the named property, that is the property to which the reference refers; if that object does not contain the named property, the prototype for that object is examined next; and so on.
看图说话
构造函数 Foo 的原型属性 prototype 指向了原型对象 Foo.prototype 。f1, f2 是Foo的实例,通过指向原型对象的__proto__ 就可以继承原型对象上公有的方法。同时,Foo.prototype 上constructor 属性指回 构造函数 Foo。
构造函数Foo本身也是对象,所以也有 __proto__ ,指向了Foo的构造函数的原型对象,也就是Function.prototype。
原型对象也是对象,所以也有 __proto__ ,指向Object.prototype。最终Object.prototype.__proto__指向 null。
(完) :)