物件導向的編程思想在javascript中的運用(上)

來源:互聯網
上載者:User

對於正在從事或者打算從事編程的人來說,物件導向是一個耳熟能詳的詞,幾乎每一個人都能列舉出一些物件導向的程式設計語言,例如C++,JAVA,C#等等。其實,物件導向的思想是獨立於程式設計語言的,例如在C#中,在一個靜態類的靜態方法中,按照過程式開發調用一系列靜態函數,我們很難說這是物件導向的編程,相反,象jquery和extjs這樣優秀的javascript庫,卻處處體現著物件導向的設計思想。本文不打算探討javascript是否能夠算做物件導向的程式設計語言,這個問題是重視中國式考試的人應該關注的,我這裡只是簡單的說明如何在javascript中使用物件導向的編程思想。

物件導向首先要有對象。在javascript中建立一個對象非常簡單:

var o={};

<!--[endif]-->

這樣就產生了一個對象,我們可以很方便的給這個對象添加屬性和方法:

    o.name="object name";
    o.showName=function(){
            alert(o.name);
        }    <!--[endif]-->

不過大多數人還是習慣把對象的屬性和方法放在定義對象的一對{}裡邊:

var o = {
            name: "object name",
            showName: function() {
                alert(o.name);
            }
        }

     訪問屬性和方法有兩種方式,第一種:

alert(o.name);
o.showName();

     這種寫法很常見,C#中調用對象的屬性和方法也是這種方式。還有一種是javascript中比較特別的,使用屬性或者方法的名字作為索引來進行訪問:

alert(o["name"]);
o["showName"]();  

     這好像有點和孔乙己“茴香的茴字有幾種寫法”差不多了,事實上,很少有人使用索引來調用對象的屬性或者方法。
     除了我們自訂的屬性和方法,我們的對象還有一個constructor屬性以及toString()等方法。這些屬性和方法是從Object內建對象來的,所有的對象都會有這些屬性和方法。其中constructor屬性指向構造出該對象的建構函式。我們沒有使用建構函式來建立對象,事實上,js的解譯器會使用Object建構函式。如果我們自己定義了建構函式,那麼便可以通過該建構函式來建立對象,這樣可以使得建立的對象具有相同的屬性和方法,這便開始有點物件導向的味道了。好,我們從一個簡單的例子開始看看如何建立一個建構函式吧:

function Person(name, sex, age) {
            this.name = name;
            this.sex = sex;
            this.age = age;
            this.showInfo = function() {
                alert("姓名:" + this.name + " 性別:" + this.sex + " 年齡:" + this.age);
            }
        }

    我們定義了一個名字叫Person的建構函式,該建構函式有三個屬性和一個方法,通過建構函式來產生一個對象並調用方法也非常簡單:

var zhangsan = new Person("張三", "男", 18);
zhangsan.showInfo();

    運行後我們可以看到彈出一個對話方塊,顯示出這個叫張三的人的資訊:

 

    我們還可以看看對象的constructor屬性來看看zhangsan的建構函式是不是我們定義好的Person:

alert(zhangsan.constructor);

    結果

 

     可以看到,正是我們的Person建構函式。

    不過,這裡還是有點問題,每一次我們構造一個對象,都會在記憶體中為屬性和方法分配記憶體空間,而事實上,所有的對象完全可以用同一個方法,並不需要有多個方法的副本,這樣有些浪費記憶體空間。既然意識到了這個問題,讓我們來想想如何解決吧。一個很自然的想法是,既然我們只想為方法分配一次記憶體空間,那麼我們可以設定一個值用來標識方法的記憶體空間是否已經分配,按照這個思路,我們將建構函式做如下修改:

function Person(name, sex, age) {
            this.name = name;
            this.sex = sex;
            this.age = age;
            if (typeof Person._initialized == "undefined") {
                this.showInfo = function() {
                    alert("姓名:" + this.name + " 性別:" + this.sex + " 年齡:" + this.age);
                }
                Person._initialized = true;
            }
        }

    這裡,我們用一個成員_initialized來指示是否已經對方法進行了記憶體空間的分配。當第一個物件建構的時候_initialized未被定義,所以我們的判斷語句為真,這時會對方法進行了定義並分配記憶體空間,然後把_initialized的值設定為true,用以表明方法的記憶體空間已經分配了。第二個物件建構的時候則不會再進入判斷,因而也不會再一次分配記憶體空間。似乎沒什麼問題,運行一下看看,張三的資訊依然正常顯示。雖然不辛苦,不過解決了一個小問題,還是慶祝下吧,來盤迴鍋肉,我要大快朵頤。還沒開吃,一個叫李四的MM也想讓電腦彈出她的個人資訊。OK,很簡單,再構造一個對象,然後調用showInfo方法就可以了:

var lisi = new Person("李四", "女", 28);
lisi.showInfo();

    為了照顧MM,還把這段放在了張三的前邊。MM的資訊正確顯示出來了,可是張三的資料不見了。這下張三不樂意了,排名放在MM後邊也罷了,但好歹得有名字啊。這可苦了我這編程人員,回鍋肉看來沒辦法吃了,先改bug吧。開啟firebug,看到MM的資訊顯示之後出現錯誤,提示為:zhangsan.showInfo is not a function。設定斷點看看,構造zhangsi對象以後發現並沒有showInfo這個方法。原來showInfo方法雖然只有一個,但是存在於第一個對象之中,第二個對象並不能訪問。那麼,究竟如何才能讓同一個建構函式產生的對象共用同一個函數呢?javascript中的prototype給我們提供了這個功能。根據javascript的規範中描述,每一個建構函式都有一個prototype屬性用於實現繼承和屬性的共用。我們的showInfo方法也可以看作是一個屬性,該屬性指向一個函數的引用。現在我們使用prototype來使得我們的方法可以共用,代碼的改動很簡單,把this.showInfo改成Person.prototype.showInfo就可以了,改動之後的代碼如下:

function Person(name, sex, age) {
            this.name = name;
            this.sex = sex;
            this.age = age;
            if (typeof Person._initialized == "undefined") {
                Person.prototype.showInfo = function() {
                    alert("姓名:" + this.name + " 性別:" + this.sex + " 年齡:" + this.age);
                }
                Person._initialized = true;
            }
        }

    使用該建構函式產生兩個對象:

var lisi = new Person("李四", "女", 28);
lisi.showInfo();
var zhangsan = new Person("張三", "男", 18);
zhangsan.showInfo();   

    運行之後先顯示李四的資訊,然後是張三的資訊。現在兩個人都滿意了,可惜我的回鍋肉已經涼了

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.