學好JS的面向對象,能很大程度上提升代碼的重用率,像jQuery,easyui等,這篇博客主要從細節上一步步講JS中如何有效地建立對象,也能夠看到常見的建立對象的方式,最後也會附上一些JS面向對象的案例。html
1、面向對象(Java面向對象亦是如此)數組
1.對象:對象是一個總體,對外提供一些操做。函數
2.面向對象:使用對象時,只關注對象提供的功能,不關注其內部細節。好比電腦——有鼠標、鍵盤,咱們只須要知道怎麼使用鼠標,敲打鍵盤便可,沒必要知道爲什麼點擊鼠標能夠選中、敲打鍵盤是如何輸入文字以及屏幕是如何顯示文字的。總之咱們不必知道其具體工做細節,只需知道如何使用其提供的功能便可,這就是面向對象。ui
3.JS的對象組成:方法 和 屬性this
在JS中,有函數、方法、事件處理函數、構造函數,其實這四個都是函數,只是做用不一樣。函數是獨立的存在,方法屬於一個對象,事件處理函數用來處理一個事件,構造函數用來構造對象。spa
首先經過經常使用的數組來認識下JS的對象:prototype
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的,上面的定義等價於下面。3d
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>
一樣的咱們也能夠根據本身的需求爲其它的對象添加方法,好比顯示數組:code
可是咱們不能在系統對象中隨意附加方法和屬性,不然可能會覆蓋已有方法、屬性。
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的全局屬性和全局方法:
2、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>