码迷,mamicode.com
首页 > 编程语言 > 详细

JavaScript基础学习之-自定义对象(2)

时间:2015-08-15 17:56:46      阅读:114      评论:0      收藏:0      [点我收藏+]

标签:

自定义对象

一、定义类或对象
1.工厂方式
创建对象car 

 1 var oCar = new Object;
 2 oCar.color = "red";
 3 oCar.doors = 4;
 4 oCar.mpg = 23;
 5 oCar.showColor = function(){
 6    alert(this.corlor);
 7 };
 8 
 9 创建多个car
10 function createCar(color, doors, mpg) {
11     var tempcar = new Object;
12     tempcar.color = color;
13     tempcar.doors = doors;
14     tempcar.mpg = mpg;
15     tempcar.showColor = function () {
16         alert(this.color)
17     };
18    return tempcar;
19 }
20 
21 var car1 = createCar("red", 4, 23);
22 var car2 = createCar("blue", 3, 25);
23 car1.showColor();    //outputs "red"
24 car2.showColor();    //outputs "blue"

 

这个例子中,每次调用函数createCar(),都要创建新函数showColor(),意味着每个对象都有自己的showColor()版本,事实上,每个对象都共享了同一个函数。
有些开发者在工厂函数外定义对象的方法,然后通过属性指向该方法,从而避开这个问题。

 1 function showColor(){
 2    alert(this.color);
 3 }
 4 function createCar(color, doors, mpg) {
 5     var tempcar = new Object;
 6     tempcar.color = color;
 7     tempcar.doors = doors;
 8     tempcar.mpg = mpg;
 9     tempcar.showColor = showColor;
10     return tempcar;
11 }
12 
13 var car1 = createCar("red", 4, 23);
14 var car2 = createCar("blue", 3, 25);
15 car1.showColor();    //outputs "red"
16 car2.showColor();    //outputs "blue"

 

从功能上讲,这样解决了重复创建函数对象的问题,但该函数看起来不像对象的方法。所有这些问题引发了开发者定义的构造函数的出现。

2.构造函数方法

 1 function Car(sColor, iDoors, iMpg) {
 2     this.color = sColor;
 3     this.doors = iDoors;
 4     this.mpg = iMpg;
 5     this.showColor = function () {
 6         alert(this.color)
 7     };
 8 }
 9 
10 var oCar1 = new Car("red", 4, 23);
11 var oCar2 = new Car("blue", 3, 25);
12 oCar1.showColor();    //outputs "red"
13 oCar2.showColor();    //outputs "blue"

 

就像工厂函数,构造函数会重复生成函数,为每个对象都创建独立的函数版本。不过,也可以用外部函数重写构造函数,同样,这么做语义上无任何意义。

3.原型方式

 1 function Car(){
 2 }
 3 Car.prototype.color = "red";
 4 Car.prototype.doors= 4;
 5 Car.prototype.mpg= 23;
 6 Car.prototype.showColor = function(){
 7    alert(this.color);
 8 }
 9 
10 var oCar1 = new Car();
11 var oCar2 = new Car();

 


它解决了前面两种方式存在的两个问题。但并不尽人意。首先,这个构造函数没有参数。使用原型方式时,不能通过构造函数传递参数初始化属性的值,这点很令人计厌,但还没完,真正的问题出现在属性指向的是对象,而不是函数时。考虑下面的例子:

 1 function Car(){
 2 }
 3 Car.prototype.color = "red";
 4 Car.prototype.doors= 4;
 5 Car.prototype.mpg= 23;
 6 Car.prototype.drivers = new Array("Mike","Sue");
 7 Car.prototype.showColor = function(){
 8    alert(this.color);
 9 }
10 
11 var oCar1 = new Car();
12 var oCar2 = new Car();
13 oCar1.drivers.push("Matt");
14 alert(oCar1.drivers);      //outputs "Mike,Sue,Matt"
15 alert(oCar2.drivers);      //outputs "Mike,Sue,Matt"
16 
17 4.混合的构造函数/原型方式
18 function Car(sColor, iDoors, iMpg) {
19     this.color = sColor;
20     this.doors = iDoors;
21     this.mpg = iMpg;
22     this.drivers = new Array("Mike", "Sue");
23 }
24 
25 Car.prototype.showColor = function () {
26     alert(this.color);
27 };
28 
29 var oCar1 = new Car("red", 4, 23);
30 var oCar2 = new Car("blue", 3, 25);
31 
32 oCar1.drivers.push("Matt");
33 
34 alert(oCar1.drivers);    //outputs "Mike,Sue,Matt"
35 alert(oCar2.drivers);    //outputs "Mike,Sue"

 

现在就更像创建一般对象了。所有的非函数属性都有构造函数中创建,意味着又可用构造函数的参数赋予属性默认值了。因为只创建showColor()函数的一个实例,所以没有内存浪费。

5.动态原型方法

 1 function Car(sColor, iDoors, iMpg) {
 2     this.color = sColor;
 3     this.doors = iDoors;
 4     this.mpg = iMpg;
 5     this.drivers = new Array("Mike", "Sue");
 6 
 7     if (typeof Car._initialized == "undefined") {
 8 
 9         Car.prototype.showColor = function () {
10             alert(this.color);
11         };
12 
13         Car._initialized = true;
14     }
15 }
16 
17 
18 var oCar1 = new Car("red", 4, 23);
19 var oCar2 = new Car("blue", 3, 25);
20 
21 oCar1.drivers.push("Matt");
22 
23 alert(oCar1.drivers);    //outputs "Mike,Sue,Matt"
24 alert(oCar2.drivers);    //outputs "Mike,Sue"

 

动态原型方法的基本想法与混合的构造函数/原型方式相同,即在构造函数内定义非函数属性,而函数属性则利用原型属性定义。唯一的区别是赋予对象方法的位置。

6.混合工厂方式
这种方式通常是在不能应用前一种方式时的变通方法。它的目的是创建假构造函数,只返回另一种对象的新实例。

function Car() {
    var tempcar = new Object;
    tempcar.color = "red";
    tempcar.doors = 4;
    tempcar.mpg = 23;
    tempcar.showColor = function () {
        alert(this.color)
    };
   return tempcar;
}

 


与经典方式不同,这种方式使用new运算符,使它看起来像真正的构造函数。

7.采用哪种方式
   如前所述,目前使用最广泛的是混合的构造函数/原型方式。些外,动态原型方法也很流行,在功能上与前者等价,可以采用这两种方式中的任何一种。

二、修改对象
1.创建新方法
可以用prototype属性为任何已有的类定义新方法,就像处理自己的类一样。
例:

Array.prototype.indexOf = function(vItem){
   for(var i=0;i<this.length;i++){
      if(vItem == this[i]){
         return i;
      }
   }
   retunr -1;
}

 


最后,如果想给ECMAScript中的每个本地对象添加新方法,必须在Object对象的prototype属性上定义它。

2.重定义已有方法
就像能给自己的类定义新方法一样,也可重定义已有的方法。函数名只是指向函数的指针,因此可以轻易地使它指向其他函数。

 1 Function.prototype.toString = function(){
 2    return "Function code hidden";
 3 }
 4 function sayHi(){
 5    alert("hi");
 6 }
 7 alert(sayHi.toString());      //outputs "Function code hidden"
 8 
 9  
10 
11  

 

 

JavaScript基础学习之-自定义对象(2)

标签:

原文地址:http://www.cnblogs.com/x739400043/p/4732625.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!