每个函数的prototype属性都包含一个对象。
它只有在该函数是构造器函数时才会发挥作用。
该函数创建的所有对象都会持有一个该函数的prototype属性的引用,并可以将其当作自身的属性来使用。
prototype属性的简单使用:
下面我们将解决以下问题
- 每个函数都有一个prototype属性,该属性存储的就是原型对象
- 为原型对象添加属性
- 使用原型对象中的新增属性
- 区分对象自身属性与原型属性
- __proto__,用于保存各对象原型的神秘链接
- 介绍原型方法,例如:isPrototypeOf()、hasOwnProperty()、propertyIsEnumerable()
- 如何(利用原型)强化数组或字符串这样的内建对象。
-
原型属性
首先我们已经知道,在JavaScript中函数本身也是一个包含了属性(length和constructor)和方法(apply()和call())的对象。接下来我们来看函数的另外一个属性:prototype。
prototype属性在函数被创建时就和length以及constructor这些属性一起被创建了,它的初始值是一个空对象。
下面是一个实例过程
//Gadget是一个构造器,我们在创建它时已经添加了name、color属性和whatAreYou方法.它自身也有length、constructor、prototype属性和call()、apply()方法
var Gadget = function(name,color){
this.name = name;
this.color = color;
this.whatAreYou = function(){
return 'I am a '+this.color+' '+this.name;
}
}
//此时Gadget()函数的prototype属性是一个空对象
console.log(Gadget.prototype); //Object {}
//Gadget函数实质也是一个对象所以他也有constructor属性
console.log(Gadget.constructor); //function Function() { [native code] }
//我们也可以自己添加prototype属性
Gadget.prototype = {}//利用原型链添加属性和方法,通过构造器函数的prototype属性来增加该构造器所提供的的属性和方法: Gadget.prototype.price = 100; Gadget.prototype.rating = 3; Gadget.prototype.getInfo = function(){ return 'Rating: '+this.rating+',price: '+this.price; }; //如果不想他们逐一添加到原型对象中,也可以另外定义一个对象,然后将其覆盖到之前的原型上 Gadget.prototype = { price : 100, rating : 3, getInfo : function(){ return "Rating: "+this.rating+',price: '+this.price; } } var newtoy = new Gadget('webcam','black'); console.log(newtoy.name); //webcam console.log(newtoy.color); //black console.log(newtoy.whatAreYou()); //I am a black webcam console.log(newtoy.rating); //3 console.log(newtoy.price); //100 console.log(newtoy.getInfo()); //Rating: 3,price: 100 //如果我们此时修改原型,可以看到我们依然可以通过已经创建好的newtoy中访问Gadget新添加的原型方法 Gadget.prototype.get = function(what){return this[what];} console.log(newtoy.get('price')); console.log(newtoy.get('name'));
-
自身属性和原型属性
如果在一个对象自身属性中没有找到指定的属性,就回去它的原型链中继续查找这个属性。并且自身属性优先级是高于原型属性的,因此我们可以用自身属性来重写原型属性 -
枚举属性
可以用for-in来循环遍历对象,然而我们在使用for-in时需要注意:
◇ 并不是所有的属性都会在for-in中显示,例如(数组的)length属性和constructor属性就不会显示。那些已经显示的属性被称为是可枚举的,我们可以通过各个对象所提供的propertyIsEnumerable()方法来判断其中有哪些可枚举的属性
◇ 原型链中的各个属性也会被显示出来,当然前提是他们是可枚举的。我们可以通过对象的hasOwnProperty()方法来判断一个属性是对象自身属性还是原型属性。
◇ 对于所有的原型属性,propertyIsEnumerable()都会返回false,即使他是for-in中可枚举的属性
具体使用就跳过不写了。 -
isPrototypeOf()方法
每个对象都有一个isPrototypeOf()方法,这个方法会告诉我们当前对象是否是另一个指定对象的原型
网友评论