js面向對象的那點事


前言


    最近在研讀《js權威指南》對js的面向對象機制有了一定的了解,下面跟着實驗來做下讀書筆記

 

"."運算符


    在真正的去定義一個類前,我們先來看看js的一個運算符號".",它的作用是進行對象屬性的存(寫)取(讀),它的用法是

    存(寫)           對象名.屬性=值\對象\方法;

    取(讀)           對象名.屬性;

    下面來做個實驗

View Code
 1         var dog = new Object(); //新建一個dog的object對象
 2         dog.name = "boby"; //名字,直接用.給與dog這個object對象添加name屬性,並用=賦值"boby"給name這個屬性
 3         dog.voice = "wowo"; //聲音
 4         dog.weight = 50; //體重
 5 
 6         var foot = new Object(); //
 7         foot.count = 4; //腿短
 8         foot.length = 50; //腿長
 9 
10         dog.foot = foot; //直接把對象賦給dog的foot屬性
11 
12         dog.makeSound = function () {//直接把方法賦給dog的makeSound屬性
13             document.write(dog.voice + "_大家好我的名字叫_" + dog.name + "_我體重_" + dog.weight + "_kg,長了_" + dog.foot.count + "_條腿,腿長_" + dog.foot.length + "_cm,至今單身- -")
14         };
15         dog.makeSound();

    執行結果如下:可以看出"."號運算符的強大,他可以直接給任何一個對象屬性,這個屬性可以是對象和方法

wowo_大家好我的名字叫_boby_我體重_50_kg,長了_4_條腿,腿長_50_cm,至今單身- - 

 

用delete刪除對象的屬性


    用delete可以刪除對象的屬性

    用法如下:

    delete obj.property

    下面來做個實驗 

View Code
 1         var dog = new Object(); //新建一個dog的object對象
 2         dog.name = "boby"; //名字,直接用.給與dog這個object對象添加name屬性,並用=賦值"boby"給name這個屬性
 3         dog.voice = "wowo"; //聲音
 4         dog.weight = 50; //體重
 5 
 6         var foot = new Object(); //
 7         foot.count = 4; //腿短
 8         foot.length = 50; //腿長
 9 
10         dog.foot = foot; //直接把對象賦給dog的foot屬性
11 
12         dog.makeSound = function () {//直接把方法賦給dog的makeSound屬性
13             document.write(dog.voice + "_大家好我的名字叫_" + dog.name + "_我體重_" + dog.weight + "_kg,長了_" + dog.foot.count + "_條腿,腿長_" + dog.foot.length + "_cm,至今單身- -")
14         };
15         delete dog.voice;
16         dog.makeSound();

    執行結果如下:上面的例子在給dog對象添加完屬性之后,調用 delete dog.voice;把voice刪除了,所以dog.voice的輸出變成了undefined
undefined_大家好我的名字叫_boby_我體重_50_kg,長了_4_條腿,腿長_50_cm,至今單身- -

 

構造函數("類")


    在了解"."號運算符號后,我們來定義一個"狗"(dog)的"類",代碼如下:

View Code
 1         function dog(v, n, w) {
 2             this.voice = v;
 3             this.name = n;
 4             this.weight = w;
 5             this.makeSound = function () {
 6                 document.write(this.voice + "_大家好我的名字叫_" + this.name + "_我體重_" + this.weight + "_kg,至今單身- -")
 7             };
 8         }
 9 
10         var dog1 = new dog("wowo", "boby", 50);
11         dog1.makeSound();

    我們可以看到其實這個所謂的類呢它是一個function,在這里我們稱之為構造函數,那么js的構造函數和一般的函數有什么區別呢?主要表現為以下兩點

    1、構造函數有new運算符調用

    2、原文為:傳遞給它的是一個對新創建的空對象引用,將該引用作為關鍵字this的值,而且它還要對新創建的對象進行適當的初始化(上例中 dog1傳遞給了function dog 里面的this ,其實function做了dog1的初始化,就是用this.屬性來賦值,其實就等於dog1.屬性)

    執行結果如下:

wowo_大家好我的名字叫_boby_我體重_50_kg,至今單身- -

 

prototype


    我們已經能建立一個js的類了(一些其他的js模擬面向對象的技術我們先不要深究了,其實萬變不離其宗的),接下來我們來研究一下"繼承",在研究"繼承"之前我們要先對prototype有一個了解。

    prototype (原型),js中創建的每個對象都有prototype這個屬性,同時創建一個空的prototype對象(原型對象),而這個prototype屬性則"指向"prototype對象(原型對象),每個對象都繼承prototype對象(原型對象)的所有屬性。是不是拗口得要命,為此我跟着一步一步畫了圖,圖1,圖2列出了對象、構造函數、prototype屬性、prototype對象的關系:

 圖1

 

 圖2

    前面說過js所有的類都有原型對象 包括內部的類如String Date等也不例外。

 

 

 "繼承"


    有了prototype接下來js的繼承就好辦了,因為js的繼承是基於原型對象的,這里所謂的繼承是通過把一類對象公用的屬性、方法賦值給prototype對象來實現的,這樣該類的所有對象就能調用這些屬性和方法了。值得一提的是這些屬性和方法只能讀,不能寫,因為你可以想象以下,假如沒個對象都能對prototype對象進行更改,那么prototype對象就不適用於所有改類的對象了。另外一個就是在讀prototype對象的屬性的時候,對象會先查看以下自己本身有沒有這個屬性,如果有就不會再度prototype對象的屬性,如果沒才去讀prototype對象的屬性,有於這個機制,我們可以稱js的繼承在查詢的時候發生的。下面上書的原圖說明js 查詢機制:圖3

 圖3

    下面來真正用代碼來實現下繼承

View Code
 1         function dog(n, w) {
 2             //this.voice = v;
 3             this.name = n;
 4             this.weight = w;
 5             /*this.makeSound = function () {
 6                 document.write(this.voice + "_大家好我的名字叫_" + this.name + "_我體重_" + this.weight + "_kg,至今單身- -")
 7             };
 8             return "返回值";*/
 9         }
10 
11         dog.prototype.voice = "wowo";
12         dog.prototype.makeSound = function () {
13             document.write(this.voice + "_大家好我的名字叫_" + this.name + "_我體重_" + this.weight + "_kg,至今單身- -<br/>")
14         };
15 
16         var dog1 = new dog("boby", 50);
17         document.write(dog1.voice + "<br/>");
18         dog1.makeSound();
19         document.write("--------------------我是分割線----------------------<br/>");
20         var dog2 = new dog("旺財",30);
21         document.write(dog2.voice + "<br/>");
22         dog2.makeSound();

    執行結果如下:  dog.prototype.voice   dog.prototype.makeSound分別給prototype賦值voice屬性(額,這里理解為所有的狗都是"wowo"叫的,比較溫柔 和狂野的叫法我們暫不考慮) 給prototype賦了makeSound(叫)的方法,新建的dog1、dog2都能調用到

wowo
wowo_大家好我的名字叫_boby_我體重_50_kg,至今單身- -
--------------------我是分割線----------------------
wowo
wowo_大家好我的名字叫_旺財_我體重_30_kg,至今單身- -

     用了原型對象,voice和makesound只在原型對象中占空間,而不用在每個對象實例中占用空間,大大的節省了空間開銷

 

類屬性、類方法


     我們同樣可以直接給類(構造函數)賦值屬性和方法,就是所謂的類屬性和類方法,來看下面這段代碼

View Code
 1   function dog(n, w) {
 2         this.name = n;
 3         this.weight = w;
 4         }
 5 
 6         dog.voice = "wowo";
 7        
 8         dog.heavier = function (dog1, dog2) {//比較兩只狗誰比較重
 9             if (dog1.weight > dog2.weitht) {
10                 document.write(dog1.name+"_比較重");
11             }
12             else {
13                 document.write(dog2.name + "_比較重");
14             }
15         };
16 
17         var dog1 = new dog("boby", 50);
18         var dog2 = new dog("旺財", 30);
19         document.write(dog.voice + "<br/>");
20         dog.heavier(dog1, dog2);

    執行結果如下:上例直接用 dog.voice  dog.heavier給dog類賦值屬性和方法了,用的時候用dog直接調用就行
wowo
旺財_比較重

 

js類的層次結構 


    js里具體的類結構圖我就不畫了,下面給出超類和子類模型,js的所有類的基類就是object類,如圖4

 

圖4

 

    至此JS面向對象的機制寫完了,當然實戰方面,需要大家不斷的積累經驗,ps:如果覺得那里寫得不對請博友們及時指出,不想誤了別人,更不想誤了自己

copyright © Tim demo下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM