__proto__是每个对象都有的一个属性,而prototype是函数才会有的属性
对象具有属性__proto__
,可称为隐式原型
Each constructor is a function that has a property named “prototype” that is used to implement prototype-based inheritance and shared properties. Every object created by a constructor has an implicit reference (called the object’s prototype) to the value of its constructor’s “prototype” property.
When a constructor creates an object, that object implicitly references the constructor’s prototype property for the purpose of resolving property references. The constructor’s prototype property can be referenced by the program expression constructor.prototype, and properties added to an object’s prototype are shared, through inheritance, by all objects sharing the prototype. Alternatively, a new object may be created with an explicitly specified prototype by using the Object.create built-in function
function是对象,function的原型prototype也是对象,它们都会具有对象共有的特点。即:对象具有属性__proto__,每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性 时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样 一直找下去,也就是我们平时所说的原型链的概念。__proto__可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型,这也保证了实例能够访问在构造函数原型中定义的属性和方法。
funcition这个特殊的对象,除了和其他对象一样有上述_proto_属性之外,还有自己特有的属性——原型属性(prototype),这个属性是一个指针,指向一个对象,这个对象的用途就是包含所有实例共享的属性和方法(我们把这个对象叫做原型对象)。prototype是通过调用构造函数而创建的那个对象实例的原型对象。使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法,不必在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中。原型对象也有一个属性,叫做constructor,这个属性包含了一个指针,指回原构造函数。
prototype和__proto__都指向原型对象,任意一个函数(包括构造函数)都有一个prototype属性,指向该函数的原型对象,同样任意一个构造函数实例化的对象,都有一个__proto__属性(__proto__并非标准属性,ECMA-262第5版将该属性或指针称为[[Prototype]],可通过Object.getPrototypeOf()标准方法访问该属性),指向构造函数的原型对象。
所有对象都有__proto__属性,函数这个特殊对象除了具有__proto__属性,还有特有的原型属性prototype。prototype对象默认有两个属性,constructor属性和__proto__属性。prototype属性可以给函数和对象添加可共享(继承)的方法、属性,而__proto__是查找某函数或对象的原型链方式。constructor,这个属性包含了一个指针,指回原构造函数。
函数(Foo,Object)也是对象,只不过是具有特殊功能的对象而已。任何函数都可以看做是通过Function()构造函数的new操作实例化的结果
如果把函数Foo当成实例对象的话,其构造函数是Function(),其原型对象是Function.prototype;类似地,函数Object的构造函数也是Function(),其原型对象是Function.prototype
1
2
3
|
function Foo(){}; var f1 = new Foo;console.log(Foo.__proto__ === Function.prototype); //true console.log(Object.__proto__ === Function.prototype); //true |
原型对象Function.prototype的constructor属性指向构造函数Function();实例对象Object和Foo本身没有constructor属性,需要继承原型对象Function.prototype的constructor属性
1
2
3
4
5
6
7
|
function Foo(){}; var f1 = new Foo; console.log(Function.prototype.constructor === Function); //true console.log(Foo.constructor === Function); //true console.log(Foo.hasOwnProperty( 'constructor' )); //false console.log(Object.constructor === Function); //true console.log(Object.hasOwnProperty( 'constructor' )); //false |
所有的函数都可以看成是构造函数Function()的new操作的实例化对象。那么,Function可以看成是调用其自身的new操作的实例化的结果
所以,如果Function作为实例对象,其构造函数是Function,其原型对象是Function.prototype
1
2
3
|
console.log(Function.__proto__ === Function.prototype); //true console.log(Function.prototype.constructor === Function); //true console.log(Function.prototype === Function); //true |
如果Function.prototype作为实例对象的话,其原型对象是什么呢?和前面一样,所有的对象都可以看成是Object()构造函数的new操作的实例化结果。所以,Function.prototype的原型对象是Object.prototype,其原型函数是Object()
1
|
console.log(Function.prototype.__proto__ === Object.prototype); //true |
第二部分介绍过,Object.prototype的原型对象是null
1
|
console.log(Object.prototype.__proto__ === null ); //true |
总结
【1】函数(Function也是函数)是new Function的结果,所以函数可以作为实例对象,其构造函数是Function(),原型对象是Function.prototype
【2】对象(函数也是对象)是new Object的结果,所以对象可以作为实例对象,其构造函数是Object(),原型对象是Object.prototype
【3】Object.prototype的原型对象是null