JavaScript 面向對象(一) —— 基礎篇


學好JS的面向對象,能很大程度上提高代碼的重用率,像jQuery,easyui等,這篇博客主要從細節上一步步講JS中如何有效地創建對象,也可以看到常見的創建對象的方式,最后也會附上一些JS面向對象的案例。

一、面向對象(Java面向對象亦是如此)

1.對象:對象是一個整體,對外提供一些操作。

2.面向對象:使用對象時,只關注對象提供的功能,不關注其內部細節。比如電腦——有鼠標、鍵盤,我們只需要知道怎么使用鼠標,敲打鍵盤即可,不必知道為何點擊鼠標可以選中、敲打鍵盤是如何輸入文字以及屏幕是如何顯示文字的。總之我們沒必要知道其具體工作細節,只需知道如何使用其提供的功能即可,這就是面向對象。

3.JS的對象組成:方法 和 屬性

在JS中,有函數、方法、事件處理函數、構造函數,其實這四個都是函數,只是作用不同。函數是獨立的存在,方法屬於一個對象,事件處理函數用來處理一個事件,構造函數用來構造對象。

首先通過常用的數組來認識下JS的對象:

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8">
 5         <title></title>
 6         <script>
 7             
 8             /**  9  * 定義一個數組 10              */
11             var arr = [1, 2, 3, 4, 5]; 12             
13             /** 14  * 彈出 object 15  * 說明數組就是個對象 16              */
17  alert(typeof arr); 18             
19             /** 20  * 彈出5 21  * 對象的屬性 length 22              */
23  alert(arr.length); 24             
25             /** 26  * 對象的方法 push 27  * 彈出 1,2,3,4,5,6 28              */
29  arr.push(6); 30  alert(arr); 31         </script>
32     </head>
33     <body>
34     </body>
35 </html>

4.認識下JS中的this以及全局對象window

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8">
 5         <title></title>
 6         <script>
 7             /**  8  * 定義一個全局函數  9              */
10             function show(){ 11  alert(this); 12  } 13             //調用show()
14  show(); 15             
16         </script>
17     </head>
18     <body>
19     </body>
20 </html>

 此處的show()函數為一個全局函數,調用show(),alert(this)彈出來的是window對象,說明全局函數屬於window。上面定義的show()等於為window添加一個方法,全局的函數和變量都是屬於window的,上面的定義等價於下面。

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <script>
 5             /**  6  * 為window定義一個show方法  7              */
 8  window.show = function(){  9  alert(this); 10  } 11             //調用show()
12  window.show(); 13             
14         </script>
15     </head>
16 </html>

同樣的我們也可以根據自己的需求為其它的對象添加方法,比如顯示數組:

但是我們不能在系統對象中隨意附加方法和屬性,否則可能會覆蓋已有方法、屬性。

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <script>
 5             var arr = [1,2,3,4,5];  6  arr.show = function(){  7  alert(this);  8  }  9  arr.show(); //彈出 1,2,3,4,5
10         </script>
11     </head>
12 </html>

從上面的例子也可以看出來,this即表示當前函數的調用者是誰,但是在一種情況下不是的,就是使用new 來創建對象時,this並不是指向調用者的,在后面會有說明。

window是全局對象,可以看下屬於window的全局屬性和全局方法:

 

二、JS中自定義對象,逐步分析JS中的創建對象

1.通過Object創建簡單對象:

這種方式有一個非常大的弊端,就是如果我有多個人怎么辦,每次都要新建一個對象,然后添加屬性、方法,這種方式是一次性的,會產生大量重復代碼,這是不可取的。

 1 <!DOCTYPE html>
 2 <html>
 3     <meta charset="UTF-8" />
 4     <head>
 5         <script>
 6             /**  7  * 創建一個新對象  8  * new Object()創建出來的對象幾乎是空白的,需要自己添加屬性,方法  9              */
10             var person = new Object(); 11             //為person對象添加屬性
12  person.name = "jiangzhou"; 13  person.age = 22; 14             //為person對象添加方法
15  person.showName = function(){ 16  alert("姓名:"+this.name); 17  } 18  person.showAge = function(){ 19  alert("年齡:"+this.age); 20  } 21             //調用對象的方法
22  person.showName(); 23  person.showAge(); 24             
25         </script>
26     </head>
27 </html>

2.用工廠方式來構造對象:工廠,簡單來說就是投入原料、加工、出廠。

通過構造函數來生成對象,將重復的代碼提取到一個函數里面,避免像第一種方式寫大量重復的代碼。這樣我們在需要這個對象的時候,就可以簡單地創建出來了。

 1 <!DOCTYPE html>
 2 <html>
 3     <meta charset="UTF-8" />
 4     <head>
 5         <script>
 6             //構造函數:工廠
 7             function createPerson(name, age){  8                 var person = new Object();  9                 
10                 //原料
11  person.name = name; 12  person.age = age; 13                 
14                 //加工
15  person.showName = function(){ 16  alert("姓名:"+this.name); 17  } 18  person.showAge = function(){ 19  alert("年齡:"+this.age); 20  } 21                 //出廠
22                 return person; 23  } 24             //創建兩個對象
25             var p1 = createPerson("jiangzhou", 22); 26             var p2 = createPerson("tom", 20); 27             
28             //調用對象方法
29  p1.showName(); 30  p1.showAge(); 31             
32  p2.showName(); 33  p2.showAge(); 34             
35         </script>
36     </head>
37 </html>

但是,這種方式有兩個缺點:

①一般我們創建對象是通過new來創建,比如new Date(),這里使用的是方法創建。使用new來創建可以簡化一些代碼,也帶來一些新的特性。

②每個對象都有一套自己的方法,浪費資源(雖然對於現在的計算機來說不算什么,但我們盡量將設計做到最好就行了)。

這里為什么說每個對象都有自己的一套方法呢,是因為創建function()的時候其本質是通過new Function()來創建的,會誕生一個新的函數對象,所以每個對象的方法是不一樣的,這樣就存在資源浪費的問題了。看第25行代碼。

 1 <!DOCTYPE html>
 2 <html>
 3     <meta charset="UTF-8" />
 4     <head>
 5         <script>
 6             
 7             function createPerson(name, age, sex){  8                 var person = new Object();  9                 
10  person.name = name; 11  person.age = age; 12  person.sex = sex; 13                 
14  person.showName = function(){ 15  alert("姓名:"+this.name); 16  } 17  person.showAge = function(){ 18  alert("年齡:"+this.age); 19  } 20                 
21                 /** 22  * person.showSex = function(){} 等價於 person.showSex = new Function(''); 23  * 也就是說我們在創建這個函數的時候就是新建了一個對象。 24                  */
25  person.showSex = new Function('alert("性別:"+this.sex)'); 26                 
27                 return person; 28  } 29             
30             //創建兩個對象
31             var p1 = createPerson("jiangzhou", 22, ""); 32             var p2 = createPerson("Lyli", 20, ""); 33             
34  alert(p1.showName == p2.showName); //false
35             
36         </script>
37     </head>
38 </html>

3.使用new 來創建JS對象

 1 <!DOCTYPE html>
 2 <html>
 3     <meta charset="UTF-8" />
 4     <head>
 5         <script>
 6             
 7             function Person(name, age){  8                 /**  9  * 可以假想成系統會創建一個對象 10  * var this = new Object(); 11                  */
12                 
13  alert(this); //彈出Object
14                 
15                 this.name = name; 16                 this.age = age; 17                 
18                 this.showName = function(){ 19  alert("姓名:"+this.name); 20  } 21                 this.showAge = function(){ 22  alert("年齡:"+this.age); 23  } 24                 
25                 /** 26  * 假想返回了對象 27  * return this; 28                  */
29  } 30             
31             //創建兩個對象
32             var p1 = new Person("jiangzhou", 22);//可以看到在外面new了在function里面就不用new了;在function里面new了,在外面就不用new了;O(∩_∩)O~
33             var p2 = new Person("Lyli", 20); 34             
35  alert(p1.showName == p2.showName); //false
36             
37         </script>
38     </head>
39 </html>

彈出信息顯示this即是一個Object(第13行代碼)。在方法調用前使用new來創建,function內的this會指向一個新創建的空白對象,而不是指向方法調用者,而且會自動返回該對象。

但是這種方式只解決了第一個問題,每個對象還是有自己的一套方法(第35行代碼)。

 4.在function原型(prototype)上進行擴展 —— 最終版

原型添加的方法不會有多個副本,不會浪費資源,所有的對象只有一套方法(看第29行代碼)。 至於為什么是用的一套方法呢,看第31行代碼:因為所有的方法都等於原型上的方法。

 1 <!DOCTYPE html>
 2 <html>
 3     <meta charset="UTF-8" />
 4     <head>
 5         <script>
 6             
 7             /**  8  * Person構造函數:在JS中,構造函數其實就可以看成類,對某個對象的抽象定義。  9  * @param {Object} name 10  * @param {Object} age 11              */
12             function Person(name, age){ 13                 //屬性:每個對象的屬性各不相同
14                 this.name = name; 15                 this.age = age; 16  } 17             //在原型上添加方法,這樣創建的所有對象都是用的同一套方法
18  Person.prototype.showName = function(){ 19  alert("姓名:"+this.name); 20  } 21  Person.prototype.showAge = function(){ 22  alert("年齡:"+this.age); 23  } 24             
25             //創建兩個對象
26             var p1 = new Person("jiangzhou", 22); 27             var p2 = new Person("Lyli", 20); 28             
29  alert(p1.showName == p2.showName); //true
30             //這里為什么兩個對象的方法是相等的呢,可以看成如下
31  alert(p1.showName == Person.prototype.showName); //true
32             
33         </script>
34     </head>
35 </html>

通過prototype我們還可以很方便的擴展系統對象,按照自己的需求來擴展,而且又能適用於所有地方,又不會浪費資源。如下面對Array進行擴展,求數組和的方法。

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8">
 5     </head>
 6     <script>
 7         /**  8  * 對數組原型擴展一個求和的方法;  9  * 注意不能只加在某個數組對象上,那樣的話只能在那個對象上適用。 10          */
11  Array.prototype.sum = function(){ 12             var sum = 0; 13             for(var i=0;i<this.length;i++){ 14  sum += this[i]; 15  } 16             return sum; 17  } 18         //通過new Array() 和 [] 創建數組完全是一樣的效果。
19         var arr1 = new Array(1,2,3,4,5,6); 20         var arr2 = [11,22,33,44,55]; 21         
22  alert(arr1.sum()); 23  alert(arr2.sum()); 24         
25  alert(arr1.sum == arr2.sum); //true
26  alert(arr2.sum == Array.prototype.sum); //true
27     </script>
28 </html>

 

 三、案例:JavaScript 面向對象(二) —— 案例篇

 


免責聲明!

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



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