乖,別哭的薄殼
          ~一份耕耘,一份收獲~
          posts - 23,comments - 260,trackbacks - 0

          一、定義類或對象
          1.工廠方式
          創建對象car
          var oCar = new Object;
          oCar.color = "red";
          oCar.doors = 4;
          oCar.mpg = 23;
          oCar.showColor = function(){
             alert(this.corlor);
          };

          創建多個car
          function createCar(color, doors, mpg) {
              var tempcar = new Object;
              tempcar.color = color;
              tempcar.doors = doors;
              tempcar.mpg = mpg;
              tempcar.showColor = function () {
                  alert(this.color)
              };
             return tempcar;
          }

          var car1 = createCar("red", 4, 23);
          var car2 = createCar("blue", 3, 25);
          car1.showColor();    //outputs "red"
          car2.showColor();    //outputs "blue"
          這個例子中,每次調用函數createCar(),都要創建新函數showColor(),意味著每個對象都有自己的showColor()版本,事實上,每個對象都共享了同一個函數。
          有些開發者在工廠函數外定義對象的方法,然后通過屬性指向該方法,從而避開這個問題。
          function showColor(){
             alert(this.color);
          }
          function createCar(color, doors, mpg) {
              var tempcar = new Object;
              tempcar.color = color;
              tempcar.doors = doors;
              tempcar.mpg = mpg;
              tempcar.showColor = showColor;
              return tempcar;
          }

          var car1 = createCar("red", 4, 23);
          var car2 = createCar("blue", 3, 25);
          car1.showColor();    //outputs "red"
          car2.showColor();    //outputs "blue"
          從功能上講,這樣解決了重復創建函數對象的問題,但該函數看起來不像對象的方法。所有這些問題引發了開發者定義的構造函數的出現。

          2.構造函數方法
          function Car(sColor, iDoors, iMpg) {
              this.color = sColor;
              this.doors = iDoors;
              this.mpg = iMpg;
              this.showColor = function () {
                  alert(this.color)
              };
          }

          var oCar1 = new Car("red", 4, 23);
          var oCar2 = new Car("blue", 3, 25);
          oCar1.showColor();    //outputs "red"
          oCar2.showColor();    //outputs "blue"
          就像工廠函數,構造函數會重復生成函數,為每個對象都創建獨立的函數版本。不過,也可以用外部函數重寫構造函數,同樣,這么做語義上無任何意義。

          3.原型方式
          function Car(){
          }
          Car.prototype.color = "red";
          Car.prototype.doors= 4;
          Car.prototype.mpg= 23;
          Car.prototype.showColor = function(){
             alert(this.color);
          }

          var oCar1 = new Car();
          var oCar2 = new Car();
          它解決了前面兩種方式存在的兩個問題。但并不盡人意。首先,這個構造函數沒有參數。使用原型方式時,不能通過構造函數傳遞參數初始化屬性的值,這點很令人計厭,但還沒完,真正的問題出現在屬性指向的是對象,而不是函數時。考慮下面的例子:
          function Car(){
          }
          Car.prototype.color = "red";
          Car.prototype.doors= 4;
          Car.prototype.mpg= 23;
          Car.prototype.drivers = new Array("Mike","Sue");
          Car.prototype.showColor = function(){
             alert(this.color);
          }

          var oCar1 = new Car();
          var oCar2 = new Car();
          oCar1.drivers.push("Matt");
          alert(oCar1.drivers);      //outputs "Mike,Sue,Matt"
          alert(oCar2.drivers);      //outputs "Mike,Sue,Matt"

          4.混合的構造函數/原型方式
          function Car(sColor, iDoors, iMpg) {
              this.color = sColor;
              this.doors = iDoors;
              this.mpg = iMpg;
              this.drivers = new Array("Mike", "Sue");
          }

          Car.prototype.showColor = function () {
              alert(this.color);
          };

          var oCar1 = new Car("red", 4, 23);
          var oCar2 = new Car("blue", 3, 25);

          oCar1.drivers.push("Matt");

          alert(oCar1.drivers);    //outputs "Mike,Sue,Matt"
          alert(oCar2.drivers);    //outputs "Mike,Sue"
          現在就更像創建一般對象了。所有的非函數屬性都有構造函數中創建,意味著又可用構造函數的參數賦予屬性默認值了。因為只創建showColor()函數的一個實例,所以沒有內存浪費。

          5.動態原型方法
          function Car(sColor, iDoors, iMpg) {
              this.color = sColor;
              this.doors = iDoors;
              this.mpg = iMpg;
              this.drivers = new Array("Mike", "Sue");

              if (typeof Car._initialized == "undefined") {

                  Car.prototype.showColor = function () {
                      alert(this.color);
                  };

                  Car._initialized = true;
              }
          }


          var oCar1 = new Car("red", 4, 23);
          var oCar2 = new Car("blue", 3, 25);

          oCar1.drivers.push("Matt");

          alert(oCar1.drivers);    //outputs "Mike,Sue,Matt"
          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.重定義已有方法
          就像能給自己的類定義新方法一樣,也可重定義已有的方法。函數名只是指向函數的指針,因此可以輕易地使它指向其他函數。

          Function.prototype.toString = function(){
             return "Function code hidden";
          }
          function sayHi(){
             alert("hi");
          }
          alert(sayHi.toString());      //outputs "Function code hidden"

          posted on 2007-04-16 22:20 小祝 閱讀(908) 評論(4)  編輯  收藏 所屬分類: Javascript

          FeedBack:
          # re: javascript學習筆記(一)--對象
          2007-04-17 12:38 | cresposhi
          very good!
          我一般使用混合模式,是學eric的,推薦大家使用。如果弄不明白可以看看大師們的源代碼。  回復  更多評論
            
          # re: javascript學習筆記(一)--對象
          2007-04-20 19:00 | 睿不可當
          小祝 辛苦了
          這么好的文章!
          頂了!  回復  更多評論
            
          # re: javascript學習筆記(一)--對象
          2008-03-07 13:19 | 很好頂了
          很好頂了很好頂了很好頂了很好頂了很好頂了很好頂了  回復  更多評論
            
          # re: javascript學習筆記(一)--對象
          2008-04-15 23:44 | Aragorn
          老祝的文章太好了!
          我也覺得混合模式更好些,更像是創建對象的過程,而且沒有內存的浪費!
          老祝辛苦了!
          頂!  回復  更多評論
            
          主站蜘蛛池模板: 高州市| 华亭县| 库伦旗| 彭阳县| 连江县| 峨边| 石渠县| 晋中市| 蒙阴县| 梓潼县| 顺义区| 岱山县| 云安县| 白水县| 体育| 灌云县| 浮梁县| 大庆市| 临泉县| 如皋市| 杭锦后旗| 资中县| 青州市| 阜平县| 吉木乃县| 修文县| 连城县| 军事| 揭阳市| 无锡市| 定结县| 东莞市| 河津市| 南部县| 河曲县| 兴山县| 西畴县| 育儿| 遂平县| 彝良县| 建瓯市|