又是一个比较重要的知识点——原型(prototype)。
一个例子
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本身。
总结一下即是:
- prototype:JavaScript中每个函数都有一个prototype属性,此属性指向了该函数的原型对象
- __proto__:JavaScript中每一个对象(null除外),包括函数创建的对象、函数自身、原型对象,都有一个__proto__属性,指向了创建该对象的函数的原型
- constructor:该属性属于原型对象,指向相关的构造函数
继续探究
既然刚刚说了每一个对象包括原型对象都有__proto__属性,那么继续来试验:
// 接上一段代码
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__又指向了什么呢?
Object.prototype .__proto__ // null
Object.prototype.__proto__指向了null,这也说明了null是原型链的顶端。
上述的所有指向关系可以用一张图来表示:
ps:这里面有一个细节,Function.__proto__ === Function.prototype
Function作为方法,它有自己的prototype;Function作为对象,它的__proto__指向了Function.prototype,这似乎是在说:Function方法生成了Function对象?
针对这个问题,我觉得还是看这篇文章比较合适,我就不费口舌了。
可以是使用prototype做什么?
创建对象的数据共享
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
把一些实例共享的属性和方法放在原型上,节约空间。
基于原型链的委托继承
function Child(){}
function Parent(){
this.name = 'ppp'
}
Child.prototype = new Parent()
var c = new Child()
c.name // 'ppp'
这个原型继承的关系可以用图来表示:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。