亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

JavaScript定義類的幾種方式總結

2019-11-20 21:18:50
字體:
來源:轉載
供稿:網友

提起面向對象我們就能想到類,對象,封裝,繼承,多態。在《javaScript高級程序設計》(人民郵電出版社,曹力、張欣譯。英文名字是:Professional JavaScript for Web Developers)這本書中描述的還算比較詳細。我們看看JavaScript中定義類的各種方法。

1.工廠方式

javaScript中創建自己的類和對象,我們應該是必須掌握的,我們都知道javaScript中對象的屬性可以在對象創建后動態定義,比如下面的代碼:

復制代碼 代碼如下:

<script type="text/javascript">
    //定義
    var oCar = new Object();
    oCar.color = "red";
    oCar.doors = 4;
    oCar.showColor = function() {
        alert(this.color);
    }
    //調用
    oCar.showColor();
</script>

我們很容易使用oCar對象,但是我們創就是想創建多個Car實例。我們可以使用一個函數來封裝上面的代碼來實現:
復制代碼 代碼如下:

<script type="text/javascript">
    //定義
    function createCar() {
        var oCar = new Object();
        oCar.color = "red";
        oCar.doors = 4;
        oCar.showColor = function() {
            alert(this.color);
        }
        return oCar;
    }
    //調用
    var ocar1 = createCar();
    var ocar2 = createCar();
    ocar1.color = "black";
    ocar1.showColor();
    ocar2.showColor();
</script>

順便說一下,javaScript對象默認成員屬性都是public 的。這種方式我們稱為工廠方式,我們創造了能創建并返回特定類型的對象的工廠。

這樣做有點意思了,但是在面向對象中我們經常使用創建對象的方法是:

Car car=new Car();

使用new 關鍵字已經深入人心,因此我們使用上面的方法去定義總感覺別扭,并且每次調用時都去創建新的屬性以及函數,功能上也不實際。下來我們看看構造函數的形式定義類。

2.構造函數

這種方式看起來有點象工廠函數。具體表現如下:

復制代碼 代碼如下:

<script type="text/javascript">
    //定義
    function Car(color, doors) {
        this.color = color;
        this.doors = doors;
        this.showColor = function() {
            alert(this.color);
        };
    }
    //調用
    var car1 = new Car("red", 4);
    var car2 = new Car("blue", 4);
    car1.showColor();
    car2.showColor();
</script>

看起來效果很明顯,有差別了吧。感覺有點意思了。在構造函數內部創造對象使用this 關鍵字,使用new 運算符創建對象感覺非常親切。但是也有點問題:每次new 對象時都會創建所有的屬性,包括函數的創建,也就是說多個對象完全獨立,我們定義類的目的就是為了共享方法以及數據,但是car1對象與car2對象都是各自獨立的屬性與函數,最起碼我們應該共享方法。這就是原形方式的優勢所在。

3.原型方式

利用對象的prototype屬性,可把它看出創建新對象所依賴的原型。方法如下:

復制代碼 代碼如下:

<script type="text/javascript">
    //定義
    function Car() {
    };
    Car.prototype.color = "red";
    Car.prototype.doors = 4;
    Car.prototype.drivers = new Array("Tom", "Jerry");
    Car.prototype.showColor = function() {
        alert(this.color);
    }
    //調用:
    var car1 = new Car();
    var car2 = new Car();
    car1.showColor();
    car2.showColor();
    alert(car1.drivers);
    car1.drivers.push("stephen");
    alert(car1.drivers); //結果:Tom,Jerry,stephen
    alert(car2.drivers); //結果:Tom,Jerry,stephen

 

//可以用json方式簡化prototype的定義:

        Car.prototype =
        {
            color: "red",
            doors: 4,
            drivers: ["Tom", "Jerry",'safdad'],
            showColor: function() {
                alert(this.color);
            }
        }
</script>


首先這段代碼的構造函數,其中沒有任何代碼,接下來通過對象的prototype屬性添加屬性定義Car對象的屬性。這種方法很好,但是問題是Car的對象指向的是Array指針,Car的兩個對象都指向同一個Array數組,其中一個對象car1改變屬性對象的引用(數組Array)時,另一個對象car2也同時改變,這是不允許的。

同時該問題也表現在原型不能帶任何初始化參數,導致構造函數無法正常初始化。這需要另一種方式來解決:那就是混合的構造函數/原型模式。

4. 混合的構造函數/原型模式

聯合使用構造函數和原型方式,定義類就非常方便。

復制代碼 代碼如下:

<script type="text/javascript">
//定義
    function Car(color,doors)
   {
        this.color=color;
        this.doors=doors;
        this.drivers=new Array("Tom","Jerry");
   }

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

   //調用:
   var car1=new Car('red',4);
   var car2=new Car('blue',4);

   car1.showColor();
   car2.showColor();

   alert(car1.drivers);
   car1.drivers.push("stephen");
   alert(car1.drivers); //結果:Tom,Jerry,stephen
   alert(car2.drivers); //結果:Tom,Jerry
   alert(car1 instanceof Car);

</script>


該方法是把屬性放在內部定義,把方法放在外邊利用prototype進行定義。解決了第三種方法的問題。

這種方法其實應該來說非常友好了,但是比起java的語法來,應該有一些不和諧,感覺比較凌亂,對C++來說,我們就沒有那么麻煩的感覺了,可是開發C++的研發人員一般情況下很少涉及javaScript,而對J2EE的研發人員來說,這種方式總有一些別扭??偢杏X不是友好的封裝,其實只不過是視覺上封裝效果不是很好而已,要想達到視覺封裝效果而又能達到這種方法的效果的也可以以,個人認為其實比較麻煩。那就是動態原型法。

5.動態原型

對于習慣使用其他語言的開發者來說,使用混合的構造函數/原型方式感覺不那么和諧。畢竟,定義類時,大多數面向對象語言都對屬性和方法進行了視覺上的封裝??紤]下面的C#類:

復制代碼 代碼如下:

class Car //class
{
    public string color = "red";
    public int doors = 4;
    public int mpg = 23;

    public Car(string color, int doors, int mpg) //constructor
    {
        this.color = color;
        this.doors = doors;
        this.mpg = mpg;
    }
    public void showColor() //method
    {
        Console.WriteLine(this.color);
    }
}


C#很好的打包了Car類的所有屬性和方法,因此看見這段代碼就知道它要實現什么功能,它定義了一個對象的信息。批評混合的構造函數/原型方式的人認為,在構造函數內存找屬性,在其外部找方法的做法不合邏輯。因此,他們設計了動態原型方法,以提供更友好的編碼風格。

動態原型方法的基本想法與混合的構造函數/原型方式相同,即在構造函數內定義非函數屬性,而函數屬性則利用原型屬性定義。唯一的區別是賦予對象方法的位置。下面是用動態原型方法重寫的Car類:

復制代碼 代碼如下:

    <script type="text/javascript">
        //定義
        function Car() {
            this.color = "red";
            this.doors = 4;
            this.drivers = new Array("Tom", "Jerry");
            if (typeof Car._initialized == "undefined") {
                Car.prototype.showColor = function() {
                    alert(this.color);
                }
                //............
            }
            //最后定義
            Car._initialized = true;
        }
    </script>

直到檢查typeof Car._initialized是否等于"undefined"之前,這個構造函數都未發生變化。這行代碼是動態原型方法中最重要的部分。如果這個值未定義,構造函數將用原型方式繼續定義對象的方法,然后把Car._initialized設置為true。如果這個值定義了(它的值為true時,typeof的值為Boolean),那么就不再創建該方法。簡而言之,該方法使用標志(_initialized)來判斷是否已給原型賦予了任何方法。該方法只創建并賦值一次,為取悅傳統的OOP開發者,這段代碼看起來更像其他語言中的類定義了。

6  混合工廠方式

這種方式通常是在不能應用前一種方式時的變通方法。它的目的是創建假構造函數,只返回另一種對象的新實例。這段代碼看來與工廠函數非常相似:

復制代碼 代碼如下:

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

與經典方式不同,這種方式使用new運算符,使它看起來像真正的構造函數:
var oCar = new Car();

由于在Car()構造函數內部調用了new運算符,所以將忽略第二個new運算符(位于構造函數之外)。在構造函數內部創建的對象被傳遞回變量var。這種方式在對象方法的內部管理方面與經典方式有著相同的問題。強烈建議:除非萬不得已(請參閱第15章),還是避免使用這種方式。

總結:(采用哪種方式)
目前使用最廣泛的是混合的構造函數/原型方式。此外,動態原型方法也很流行,在功能上與構造函數/原型方式等價??梢圆捎眠@兩種方式中的任何一種。不過不要單獨使用經典的構造函數或原型方式,因為這樣會給代碼引入問題。

復制代碼 代碼如下:

//ps
//static class (1:function)
    var CarCollection = new function() {
        var _carCollection = new Array(); //global,private
        this.Add = function(objCar) {
            alert('Add');
        }
        this.Get = function(carid) {
            alert('Get');
        }
    }

//static class (2:json)


    var Car = {
        color: 'red',
        doors: 4,
        showColor: function() { alert(this.color); }
    }
    Car.showColor();

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91国产中文字幕| 国产一区二区黑人欧美xxxx| 国产精品女人久久久久久| 北条麻妃一区二区在线观看| 亚洲激情视频在线播放| 国外色69视频在线观看| 91欧美激情另类亚洲| 国产精品久久久久免费a∨大胸| www.国产一区| 国产亚洲欧美日韩一区二区| 最新国产成人av网站网址麻豆| 欧美福利在线观看| 中文字幕日韩av综合精品| 亚洲一区二区三区乱码aⅴ蜜桃女| 国产精品成av人在线视午夜片| 久久精品视频在线播放| 亚洲国产精品电影| 亚洲欧美日韩图片| 96精品久久久久中文字幕| 欧美成人黄色小视频| 国产精品成人va在线观看| 日本精品一区二区三区在线播放视频| 国产亚洲精品va在线观看| 国产热re99久久6国产精品| 久久黄色av网站| 亚洲国产精品久久精品怡红院| 精品高清一区二区三区| 国产精品福利片| 欧美极品欧美精品欧美视频| 国产91网红主播在线观看| 午夜精品一区二区三区在线视| 欧美日韩精品在线播放| 色哟哟入口国产精品| 日韩免费av一区二区| 91大神在线播放精品| 97国产成人精品视频| 青青草99啪国产免费| 亚洲在线免费视频| 黑丝美女久久久| 日本中文字幕久久看| 国产精品香蕉av| 日本高清不卡在线| xxxx性欧美| 81精品国产乱码久久久久久| 欧美大片va欧美在线播放| 欧美成人自拍视频| 国产欧美精品xxxx另类| 亚洲高清久久久久久| 亚洲毛片在线观看.| 亚洲乱码一区二区| 成人激情综合网| 久久久999精品| 麻豆乱码国产一区二区三区| 国产视频亚洲精品| 综合网中文字幕| 精品丝袜一区二区三区| 日本精品免费一区二区三区| 日韩国产欧美精品在线| 欧美日本啪啪无遮挡网站| 91精品国产九九九久久久亚洲| 97色伦亚洲国产| 久久精品精品电影网| 色哟哟入口国产精品| 久久成人综合视频| 91精品国产乱码久久久久久久久| 成人伊人精品色xxxx视频| 亚洲欧美福利视频| 欧美肥婆姓交大片| 亚洲黄色有码视频| 欧美色道久久88综合亚洲精品| 日韩精品免费在线视频观看| 亚洲女人天堂av| 91精品在线观| 亚洲最大的网站| 欧美午夜无遮挡| 九九热99久久久国产盗摄| 欧美电影在线观看网站| 欧美一级片免费在线| 日韩在线视频导航| 91精品啪在线观看麻豆免费| 欧美极品xxxx| 日韩小视频在线观看| 欧美午夜精品在线| 永久免费毛片在线播放不卡| 91精品综合视频| 亚洲日韩欧美视频| 成人免费淫片视频软件| 97色在线视频观看| 精品久久久久久久中文字幕| 91av视频在线播放| 久久精品成人一区二区三区| 成人黄色av播放免费| 亚洲缚视频在线观看| 国产精品日日做人人爱| 国产91免费看片| 97精品视频在线播放| 久久亚洲精品小早川怜子66| 国产+人+亚洲| 成人日韩在线电影| 亚洲激情自拍图| 日本高清久久天堂| 亚洲黄页视频免费观看| 国产成人jvid在线播放| 国产伦精品一区二区三区精品视频| 97av在线视频免费播放| 亚洲精品之草原avav久久| 91精品综合视频| 国产日韩精品在线观看| 亚洲国产高清自拍| 日韩欧美亚洲一二三区| 亚洲国产欧美精品| 91精品国产高清久久久久久| 九九九热精品免费视频观看网站| 久久久久国色av免费观看性色| 国产成人精品午夜| 亚洲美女性生活视频| 亚洲人成人99网站| 欧美激情综合色| 久久久久久12| 久久久久久久爱| 日本欧美黄网站| 夜夜躁日日躁狠狠久久88av| 91a在线视频| 国产成人精品亚洲精品| 精品视频在线导航| 日韩免费在线播放| 精品人伦一区二区三区蜜桃免费| 亚洲男女自偷自拍图片另类| 色综合影院在线| 亚洲国产成人精品久久久国产成人一区| 亚洲成人黄色网址| 92裸体在线视频网站| 日韩视频永久免费观看| 久久欧美在线电影| 欧美另类第一页| 国产欧美精品一区二区三区介绍| 国产精品视频男人的天堂| 欧美大片va欧美在线播放| 综合欧美国产视频二区| 中文.日本.精品| 在线播放国产一区二区三区| 福利一区福利二区微拍刺激| 久久国产加勒比精品无码| 欧美精品生活片| 国产综合色香蕉精品| 96pao国产成视频永久免费| 亚洲欧洲日本专区| 欧美黑人一级爽快片淫片高清| 亚洲伊人一本大道中文字幕| 亚洲精品久久久久久久久久久久| 91精品国产色综合久久不卡98口| 91热福利电影| 亚洲a级在线观看| 国产日韩综合一区二区性色av| 久久久这里只有精品视频| 精品久久久久久亚洲精品| 中文字幕成人在线| 亚洲aa中文字幕| 国产欧美在线视频| 日本久久久a级免费| 国产精品毛片a∨一区二区三区|国| 国内精品视频在线| 日韩中文字幕亚洲| 精品亚洲va在线va天堂资源站|