对象上都有__proto__属性(函数也是对象)浏览器
通常状况下对象的__proto__属性指向该对象的构造函数的原型对象。函数
函数上才有prototype属性,该属性指向该函数的原型对象。ui
OK,下面来详细解释一下this
这个实际上是一个 internal slot (翻译成内置槽?),叫作 [[ prototype ]] ,也称为隐式原型。在js里全部的普通对象都会有。它的值要么是 null(原型链的最终), 要么仍是一个对象。spa
以前并无一个标准的方法来访问这个值,可是大多数浏览器都支持经过用.__proto__来获得它的值。因此 [[ prototype ]] 就被叫成了 __proto__ 。直到ES5中增长了标准的方法 :Object.getPrototypeOf()prototype
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.
全部用 function 语句、函数字面量或者 Function 构造函数定义的函数都会同时自动建立一个 prototype 属性,指向该函数的原型对象。code
另外,经过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。
(完) :)