Javascript Prototype (一)转

本文深入探讨JavaScript中的prototype属性,解释其工作原理及如何通过构造函数为对象添加属性和方法。同时,对比自身属性与prototype属性的区别。

关于prototype 属性

函数(functions)在javascript中本身就是对象,它有方法和属性。关于函数的属性,prototype是比较重要的一个。

Js代码 复制代码
  1. function foo(a,b){   
  2.   return a*b;   
  3. }   
  4.   
  5. typeof foo.prototype;//object  
function foo(a,b){
  return a*b;
}

typeof foo.prototype;//object

 

可以为prototype添加属性,

Js代码 复制代码
  1. foo.prototype={}  
foo.prototype={}

这个属性对foo函数没有任何影响,仅仅当foo作为构造函数的时候。prototype才会有意义.

 

给prototype添加属性和方法

前几节学过的用构造函数创建对象,主要的思路还是用new操作符访问this。这个this包含了构造函数返回的对象。我们可以往this里添加属性和方法也就是,也就是给这个对象添加了属性和方法。让我们看看下列的代码

Js代码 复制代码
  1. function Gadget(name,color){   
  2.     this.name=name;   
  3.     this.color=color;   
  4.     this.whatAreYou=function(){   
  5.         return 'I am a '+this.color+' '+this.name;   
  6.     }   
  7. }  
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代码 复制代码
  1. Gedget.prototype.price = 100;   
  2. Gedget.prototype.rating= 3;   
  3. Gedget.prototype.getInfo=function(){   
  4.      return 'Rating: '+this.rating+',price: '+this.price;   
  5. }  
Gedget.prototype.price = 100;
Gedget.prototype.rating= 3;
Gedget.prototype.getInfo=function(){
     return 'Rating: '+this.rating+',price: '+this.price;
}

 如果你感觉这么写很麻烦我们也可以用到以前创建对象所用到的方法

Js代码 复制代码
  1. Gadget.prototype = {   
  2.   price: 100,   
  3.   rating: 3,   
  4.   getInfo: function() {   
  5.     return 'Rating: ' + this.rating + ', price: ' + this.price;   
  6.   }   
  7. };  
Gadget.prototype = {
  price: 100,
  rating: 3,
  getInfo: function() {
    return 'Rating: ' + this.rating + ', price: ' + this.price;
  }
};

 这两种方法都是一样的。

 

调用Prototype的属性和方法

所有的属性和方法都可以添加到prototype中,对于对象是直接可以访问的。如果创建了一个对象,就可以访问所有的属性和方法了。

Js代码 复制代码
  1. var newtoy = new Gadget('webcam','black');   
  2. newtoy.name;//webcam   
  3. newtoy.color;//black   
  4. newtoy.whatAreYou();//I am black webcam   
  5. newtoy.price;//100   
  6. newtoy.rating;//3   
  7. newtoy.getInfo();//Rating:3,price:100  
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

对象的传递,实质上传递的是个引用,也就意味这每次创建个对象,prototype属性并不是复制而成,这样就可以动态的修改prototype的属性,所有创造的对象的属性也就会随着prototype的更改而更改。代码如下

Js代码 复制代码
  1. Gadget.prototype.get=function(what){   
  2.    return this[what];   
  3. }   
  4.   
  5. newtoy.get('price');//100   
  6. newtoy.get('color');//'black'  
Gadget.prototype.get=function(what){
   return this[what];
}

newtoy.get('price');//100
newtoy.get('color');//'black'

 newtoy对象是在get方法建立之前而生成的,但是newtoy还是可以访问get方法的。这就是prototype的妙处。

 

自身属性和prototype属性的对比

在上个例子中getInfo这个方法,用的是this来调用rating和price的。当然也可以用Gedget.prototype来重写这个方法

Js代码 复制代码
  1. Gadget.prototype.getInfo = function() {   
  2. return 'Rating: ' + Gadget.prototype.rating + ', price: ' + Gadget.prototype.price;   
  3. };  
Gadget.prototype.getInfo = function() {
return 'Rating: ' + Gadget.prototype.rating + ', price: ' + Gadget.prototype.price;
};

这个上面的方法有什么不同?首先要了解prototype更多的细节问题.

Js代码 复制代码
  1. var newtoy = new Gadget('webcam','black');  
var newtoy = new Gadget('webcam','black');

 当访问newtoy.name的时候,Javascript引擎会检索这个对象的所有属性直到找到name的属性,并返回它的值。

 

Js代码 复制代码
  1. newtoy.name;//webcam  
newtoy.name;//webcam

如果访问rating会怎么样呢?Javascript引擎首先会检索这个对象的所有属性,发现并没有叫rating这个属性。然后再去找创造这个对象的构造函数的prototype(也就是newtoy.constructor.prototype).如果这个属性找到就返回。

Js代码 复制代码
  1. newtoy.rating;//3  
newtoy.rating;//3

当然这么访问和如下代码是一样的

Js代码 复制代码
  1. newtoy.constructor.prototype.rating;//3  
newtoy.constructor.prototype.rating;//3

对prototype的属性进行重写

前几个例子说明了如果没有自身的属性,就会找prototype的属性。下面引出了这样一个问题,如果自身的属性和prototype的属性都一样的话,会怎么样呢。看如下代码

Js代码 复制代码
  1. function Gadget(name) {   
  2.   this.name = name;   
  3. }   
  4. Gadget.prototype.name = 'foo';//foo  
function Gadget(name) {
  this.name = name;
}
Gadget.prototype.name = 'foo';//foo

 在创建一个新的对象

Js代码 复制代码
  1. var toy = new Gadget('camera');   
  2. toy.name;//camera  
var toy = new Gadget('camera');
toy.name;//camera

 发现了toy.name的值是camera.这就相对于prototype的name属性进行重写。

Js代码 复制代码
  1. delete toy.name;//true   
  2. toy.name;//foo  
delete toy.name;//true
toy.name;//foo

 如果删除自身属性name,prototype的属性name就生效了

 当然你可以重新创建toy的属性

Js代码 复制代码
  1. toy.name='camera';   
  2. toy.name;//camera  
toy.name='camera';
toy.name;//camera

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值