javascript對象建立及繼承

  1 //******************************************************************************
  2 //建立類的多種方式
  3 //------------------------------------------------------------------------------
  4 //1.這種建立模式相似於c#中的靜態類,不能建立實例,成員都是屬於類的.在全局中只有一個.
  5 var class1= {
  6     item1:'item1.value',
  7     item2:'item2,value',
  8     func1:function(){
  9         console.log('我是在建立類時就建立的方法');
 10     }
 11 }
 12 //這種類不能直接使用prototype屬性去添加類成員,且class1的__proto__(原型對象:這個東西
 13 //暫時不作解釋,會在下面的繼承中解釋)是Object對象
 14 //由於Object對象是一個基對象,不存在父級,因此這個方法無法去添加修改
 15 //class_name.prototype.method_name = function(first_argument) {
 16     // body...
 17 //};
 18 //若是這個類再添加屬性的話,能夠直接編寫類方法
 19 class1.func2 = function() {
 20     // body...
 21     console.log('我是建立類後擴充的方法');
 22 };
 23 //------------------------------------------------------------------------------
 24 //2.構造函數建立類的形式.也能夠直接寫成 function class2(i1,i2).這樣建立類的方式就
 25 //  至關於建立了一個非靜態的類,須要使用 new 關鍵字來實例,若是不用 new關鍵字實例,
 26 //  則裏面的this則爲父級this,可能就會成爲window對象
 27 function class2(i1,i2){
 28     this.item1=i1;
 29     this.item2=i2;
 30     this.fun1=function(){
 31         console.log('我是在建立類時就建立的方法');
 32     }
 33 }
 34 //添加靜態方法的形式,使用這種方式添加的類成員在 new 出的對象中是不存在的,其實就相
 35 //當於從新建立了一個重名的class2的靜態類,固然若是使用 new 關鍵字去建立,則至關於創
 36 //建了一個新的class2.func2對象
 37 class2.func2 = function(i1,i2)
 38 {
 39     this.item1=i1;//若是使用的是class2.func2()的調用形式,這這裏的this指的是class2這個靜態類
 40     this.item2=i2;//若是使用的是fun2 = new class2.func2(); 那麼這裏的this指的是fun2這個對象,
 41     console.log('我是建立類後擴充的方法:直接使用[類名.屬性=function]方式建立的');
 42 }
 43 //這種方式是在建立的對象中去添加方法的擴展形式,這些方法被擴展在建立的對象中的__proto__ (原型對象)
 44 //屬性中,固然建立的對象也能夠直接使用這個方法.這個裏面的this依然指向建立的對象
 45 class2.prototype.func2 = function(i1,i2) {
 46     // body...
 47     this.item1=i1;
 48     this.item2 = i2;
 49     console.log('我是建立類後擴充的方法:使用prototype屬性擴充的方法');
 50 };
 51 //--------------------------------------------------------------------------------
 52 //3.使用new Object()建立對象,這種建立對象的形式和第一種相似,同樣是一個靜態的方法
 53 //  這種方式在使用過程當中,類中定義的成員在編寫的時候可能不在一塊兒,結構不太清晰.(我的不太推薦使用這種方式擴展)
 54 var class3 = new Object();
 55 class3.item1='123';
 56 class3.item2='345';
 57 class3.func1=function(){
 58     console.log('我是在建立類時就建立的方法');
 59 }
 60 //這個地方就不在作解釋爲何不能夠了,詳情能夠去看一下案例1
 61 //class3.prototype.func2 = function(i1,i2) {
 62 //    this.item1=i1;
 63 //    this.item2 = i2;
 64 //    console.log('我是建立類後擴充的方法:使用prototype屬性擴充的方法');
 65 //};
 66 //---------------------------------------------------------------------------------
 67 //4.使用構造函數方法去建立對象,這種建立形式是不須要new的,可是這種形式建立的類也是沒
 68 //  較好的方法去擴展的,其實這個對象並非class4,而是的到的一個object對象.
 69 //  若是不作繼承的狀況下可使用這個方式,(我的不太推薦這種使用方式,擴展性過差)
 70 function class4(i1,i2)
 71 {
 72     var o =new Object();
 73     o.item1=i1;
 74     o.item2=i2;
 75     o.func1=function(){
 76         console.log('我是在建立類時就建立的方法');
 77     }
 78     return o;
 79 }
 80 //----------------------------------------------------------------------------------
 81 //**********************************************************************************
 82 //類的繼承
 83 //我的心得:
 84 //    在js中沒有過於明確的繼承寫法.繼承寫法頁多種多樣.網上一搜一大堆.在這裏我在
 85 //    寫出的案例中主要是應用了__proto__(原型對象),和call()添加靜態方法
 86 //我的解釋:
 87 //    __proto__[原型對象]:
 88 //        這個對象實際上是指向這個對象到底都是什麼,咱們若是打開調試工具去查看這個對象,會發現這個對象有可能還有一個__proto__屬性
 89 //        可是咱們按照層級去一級一級的找下去,發現最後一層必然是Object對象,然而Object是沒有__proto__屬性的,這也就是說爲何在上
 90 //        面的靜態類是沒有辦法使用prototype屬性去擴展的緣由.prototype實際上是把方法添加到了他的上一層的對象中.固然也能夠在當前對
 91 //        象中使用.這也就是說爲何在個人繼承方式中會用到prototype屬性去設置對象的__proto__
 92 //    call()[這個方法是用於改變this指向的]:
 93 //        obj.call(this[,paras]);這個方法是用於改變this的指向,意思是在obj方法在調用的過程當中改變其中的this對象.固然咱們也能夠在call方法調用的時候傳遞參數.傳遞時在this後面追加.
 94 //        下面咱們會舉例說明call方法的做用
 95 //----------------------------------------------------------------------------------
 96 //1.call()方法做用
 97 var i1=10,i2=10;//建立兩個變量,這兩個變量是屬於window的,咱們全局的this其實就是window
 98 function test()
 99 {
100     console.log('i1+i2='+(this.i1+this.i2));//咱們輸出,i1與i2的和;這裏要記得寫 this.i1 不要直接寫 i1.由於 call方法只是改變this,單純的寫i1指的仍是window下的i1
101 }
102 test();//先執行一次,看下輸出結果
103 var obj ={i1:20,i2:20};
104 test.call(obj);//這時候咱們使用call方法,這個方法中咱們傳入一個對象,這個對象中有i1和i2兩個屬性值爲20,看一下輸出結果爲40
105 //解釋:在第一次執行的時候test方法中的 this 是 window對象,在使用 call方法後,test中的this 變化成了 obj對象
106 //-----------------------------------------------------------------------------------
107 //2.類的繼承正題
108 /*
109 父級類:包含屬性有名稱/長度/高度/體重
110 */
111 function Animal(){
112     this.name='';
113     this.length = 0;
114     this.height = 0;
115     this.weight = 0;
116     this.hello=function(){
117         console.log("我是"+this.name+'...');
118     }
119 }
120 /*
121 子類:包含游泳方法/而且重寫父級的hello方法
122 */
123 function Duck(){
124     //for(var item in this.__proto__)
125     //{
126     //    eval('this.'+item+'= this.__proto__[item]');
127     //    console.log(item);
128     //};
129     var base = this.__proto__ = new Animal();//註解1
130     Animal.call(this);//註解2
131     this.hello=function(){
132         console.log("我是"+this.name+",我是一隻小鴨子.");
133         base.hello.call(this);//註解3
134     }
135     this.swim =function(){
136         console.log('我在游泳')
137     }
138 }
139 //[註解]
140 //1:把duck對象的原型對象設置爲一個新的Animal對象,而且存到base變量中,用於讓子集重寫父級方法時調用父級方法使用.
141 //2:把當前的duck對象的this 放入 Animal方法中去執行,這樣的話 duck中的this 就能夠被附上Animal類中一樣的成員從而實現繼承
142 //3:由於base裏面存放的是一個Animal對象,這樣的話若是直接執行base.hello的話,base的this是Animal.
143 //  然而咱們如今並非想輸出Animal對象的name屬性,而是輸出duck對象的name屬性,因此這個地方用call方法替換base.hello的this爲duck對象
144 //--------------------------------------------------------------------------------------
145 //3.繼承中的方法擴展測試
146 Duck.prototype.getWeight=function(){
147     console.log(this.weight);
148 }
149 //說明:若是按照上面的繼承方式,Duck的__proto__對象被改變爲了Animal,因此在此以前使用prototype向__proto__中添加的方法就被覆蓋了.
150 //     因此就沒有辦法添加到Duck類中了.若是想經過prototype屬性添加方法的狀況下,則須要把Duck方法中的註釋去除,執行遍歷語句.
151 //     先把擴展方法添加到this對象中,而後再去替換__proto__對象中的內容
152 //建議:
153 //     這裏就建議在建立類的時候直接把裏面的屬性方法建立徹底,儘可能不要使用prototype這種方式去擴充成員.
154 //     由於這種形式是在當前對象的__proto__(原型對象)中去添加的.
相關文章
相關標籤/搜索