又是一个比较重要的知识点——原型(prototype)。html
function F() {} var f = new F() F.prototype // {constructor: ƒ} f.__proto__ // {constructor: ƒ} F.prototype === f.__proto__ // true F.prototype.constructor === F // true
能够看到F函数有一个属性prototype指向了一个对象{constructor: ƒ},由F函数new出来的对象f有一个属性__proto__指向一个对象{constructor: ƒ}。且f.__proto__和F.prototype指向了同一个对象。F.prototype有一个constructor属性又指回了F自己。
总结一下便是:git
既然刚刚说了每个对象包括原型对象都有__proto__属性,那么继续来试验:github
// 接上一段代码 F.__proto // ƒ () { [native code] } F.prototype.__proto__ // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …} F.__proto__ === Function.prototype // true F.prototype.__proto__ === Object.prototype // true
首先,F做为一个函数的同时它也是对象,因此它拥有属性__proto__指向了Function.prototype,由于全部的函数均可以理解为Function的实例;一样的,F.prototype做为一个对象,它的__proto__指向Object.prototype,由于它是对象且没有指明的构造函数,因此它直接是Object函数生成的实例,天然__proto__就指向Object.prototype。函数
如今再来探究一下Object.prototype做为一个对象,它的__proto__又指向了什么呢?this
Object.prototype .__proto__ // null
Object.prototype.__proto__指向了null,这也说明了null是原型链的顶端。spa
上述的全部指向关系能够用一张图来表示:
ps:这里面有一个细节,Function.__proto__ === Function.prototype
Function做为方法,它有本身的prototype;Function做为对象,它的__proto__指向了Function.prototype,这彷佛是在说:Function方法生成了Function对象?
针对这个问题,我以为仍是看这篇文章比较合适,我就不费口舌了。prototype
建立对象的数据共享code
function Person(){} Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var person1 = new Person(); person1.sayName(); //"Nicholas" var person2 = new Person(); person2.sayName(); //"Nicholas" alert(person1.sayName == person2.sayName); //true
把一些实例共享的属性和方法放在原型上,节约空间。htm
function Child(){} function Parent(){ this.name = 'ppp' } Child.prototype = new Parent() var c = new Child() c.name // 'ppp'
这个原型继承的关系能够用图来表示:对象