javacript设计模式之prototype

javacript设计模式之prototype
1.函数等同于对象
函数(functions)在javascript中本身就是对象,它有方法和属性。关于函数的属性,prototype是比较重要的一个
Js代码
<body>
<script language="javascript">
function foo(a,b){
  return a*b;
}

alert(typeof foo.prototype);//object
</script>
</body>
我们可以为foo.prototype添加方法和属性
foo.prototype={}
这个属性对foo函数没有任何影响,仅仅当foo作为构造函数的时候。prototype才会有意义.
2. 给prototype添加属性和方法
前几节学过的用构造函数创建对象,主要的思路还是用new操作符访问this。这个this包含了构造函数返回的对象。我们可以往this里添加属性和方法也就是,也就是给这个对象添加了属性和方法。让我们看看下列的代码
JS代码
function Gadget(name,color){
    this.name=name;
    this.color=color;
    this.whatAreYou=function(){
        return 'I am a '+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代码:
var newtoy = new Gadget('webcam','black');
newtoy.name;//webcam
newtoy.color;//black
newtoy.whatAreYou();//I am black webcam
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代码
var newtoy = new Gadget('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代码
function Gadget(name) {
  this.name = name;
}
Gadget.prototype.name = 'foo';//foo
在创建一个新的对象
var toy = new Gadget('camera');
toy.name;//camera          --------会调用自身的属性
发现了toy.name的值是camera.这就相对于prototype的name属性进行重写
JS代码
delete toy.name;//true  ------这里只是删除了实例toy.name的属性,而没有Gadget.name的属性
toy.name;//foo  
如果删除自身属性name,prototype的属性name就生效了
当然你可以重新创建toy的属性
JS代码
toy.name='camera';
toy.name;//camera
6这就对象的易变性
在javascript中,一切都是对象(除了那三各原始数据类型,在必要的时候也会包装成为对象),而且对象都是易变的(mutable).这意味着你能使用一些在大多数别的语言中不允许的技术,例如为函数添加属性:
JS代码
function Person(name,age)        //Class Person
{
this.name=name;   //构造方法里增加Person类的属性
this.age=age;
}
Person.prototype = {       //通过prototype来给Person类添加getName()方法
getName: function() {
return this.name;
},
getAge: function()     //为Person类添加getAge()方法
{
return this.age;
}
}

var alice=new Person('Alice',90);    //创建Person类的一个实例alice
var bill =new Person('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();  //对象不支持此属性或方法

你可能感兴趣的:(设计模式,js,prototype)