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();//对象不支持此属性或方法

相关推荐