javacript设计模式之prototype
javacript设计模式之prototype
1.函数等同于对象
函数(functions)在javascript中本身就是对象,它有方法和属性。关于函数的属性,prototype是比较重要的一个
Js代码
<body>
<scriptlanguage="javascript">
functionfoo(a,b){
returna*b;
}
alert(typeoffoo.prototype);//object
</script>
</body>
我们可以为foo.prototype添加方法和属性
foo.prototype={}
这个属性对foo函数没有任何影响,仅仅当foo作为构造函数的时候。prototype才会有意义.
2.给prototype添加属性和方法
前几节学过的用构造函数创建对象,主要的思路还是用new操作符访问this。这个this包含了构造函数返回的对象。我们可以往this里添加属性和方法也就是,也就是给这个对象添加了属性和方法。让我们看看下列的代码
JS代码
functionGadget(name,color){
this.name=name;
this.color=color;
this.whatAreYou=function(){
return'Iama'+this.color+''+this.name;
}
}
添加属性和方法到prototype中,是另一种给对象添加功能的方法。让我们添加下price和rating和getInfo().
JS代码
Gadget.prototype={
price:100,
rating:3,
getInfo:function(){
return'Rating:'+this.rating+',price:'+this.price;
}
};
3.调用prototype的属性和方法
所有的属性和方法都可以添加到prototype中,对于对象是直接可以访问的.如果创建了一个对象就可以访问所有的属性和方法了.
JS代码:
varnewtoy=newGadget('webcam','black');
newtoy.name;//webcam
newtoy.color;//black
newtoy.whatAreYou();//Iamblackwebcam
newtoy.price;//100
newtoy.rating;//3
newtoy.getInfo();//Rating:3,price:100
4.自身属性和prototype属性的对比
在上个例子中getInfo这个方法,用的是this来调用rating和price的。当然也可以用Gedget.prototype来重写这个方法
JS代码
Gadget.prototype.getInfo=function(){
return'Rating:'+Gadget.prototype.rating+',price:'+Gadget.prototype.price;
};
这个上面的方法有什么不同?首先要了解prototype更多的细节问题.
JS代码
varnewtoy=newGadget('webcam','black');
当访问newtoy.name的时候,Javascript引擎会检索这个对象的所有属性直到找到name的属性
JS代码
newtoy.name;//webcam
如果访问rating会怎么样呢?Javascript引擎首先会检索这个对象的所有属性,发现并没有叫rating这个属性。然后再去找创造这个对象的构造函数的prototype(也就是newtoy.constructor.prototype).如果这个属性找到就返回。
JS代码
newtoy.rating;//3
当然这么访问和如下代码是一样的
JS代码
newtoy.constructor.prototype.rating;//3
5.自身属性和prototype属性的对比
前几个例子说明了如果没有自身的属性,就会找prototype的属性。下面引出了这样一个问题,如果自身的属性和prototype的属性都一样的话,会怎么样呢。看如下代码
JS代码
functionGadget(name){
this.name=name;
}
Gadget.prototype.name='foo';//foo
在创建一个新的对象
vartoy=newGadget('camera');
toy.name;//camera--------会调用自身的属性
发现了toy.name的值是camera.这就相对于prototype的name属性进行重写
JS代码
deletetoy.name;//true------这里只是删除了实例toy.name的属性,而没有Gadget.name的属性
toy.name;//foo
如果删除自身属性name,prototype的属性name就生效了
当然你可以重新创建toy的属性
JS代码
toy.name='camera';
toy.name;//camera
6这就对象的易变性
在javascript中,一切都是对象(除了那三各原始数据类型,在必要的时候也会包装成为对象),而且对象都是易变的(mutable).这意味着你能使用一些在大多数别的语言中不允许的技术,例如为函数添加属性:
JS代码
functionPerson(name,age)//ClassPerson
{
this.name=name;//构造方法里增加Person类的属性
this.age=age;
}
Person.prototype={//通过prototype来给Person类添加getName()方法
getName:function(){
returnthis.name;
},
getAge:function()//为Person类添加getAge()方法
{
returnthis.age;
}
}
varalice=newPerson('Alice',90);//创建Person类的一个实例alice
varbill=newPerson('Bill',20);/创建Person类的一个实例alice
Person.prototype.getGreeting=function(){
return'Hi'+this.getName()+'!';//通过prototype为Person添加getGreeting()方法
};
alice.displayGreeting=function()//给alice对象添加displayGreeting()方法
{
alert(this.getGreeting());
}
alice.displayGreeting();//HiAlice!
alert(alice.getName());//Alice
alert(alice.getGreeting());//HiAlice!
bill.displayGreeting();//对象不支持此属性或方法