基本概念
對象:對象就是一個整體,對外提供一個整體。
面向對象:使用對象時,只關注對象提供的功能,不關注其內部的細節。
三個特點(類C++):封裝、繼承、多態
一些概念區別
1、方法與函數
方法:obj.fn = function(){}
函數:function fn(){}
其中函數 function fn(){} 相當於 window.fn = function(){}
2、類與對象
類:不具備實際的功能,只能用來構造對象
對象:真正有功能的東西,被類給構造出來的
封裝構造函數(工廠模式)
以person為對象舉例 (有兩個屬性 name sex)

1 <script> 2 function CreatePerson(name , sex){ 3 var obj = new Object(); 4 5 //添加屬性 6 obj.name = name; 7 obj.sex = sex; 8 9 //添加方法 10 obj.showName = function () { 11 alert(this.name); 12 }; 13 obj.showSex = function () { 14 alert(this.sex); 15 }; 16 return obj; 17 } 18 19 var p1 = CreatePerson('leo' , 'male'); 20 var p2 = CreatePerson('shawn' , 'male'); 21 p1.showName(); 22 p1.showSex(); 23 24 alert(p1.showName == p2.showName); 25 </script>
以這樣的方式(其實就是創建一個函數,然后實例對象利用函數傳參來實現,這樣做的話實例之間是沒有什么內在聯系的)來構造對象會有兩個問題:
1、沒有用到new方法
2、每個被創建的對象都有一套自己的方法(例如上述p1.showName()、p2.showName()),而這些方法的實現是一模一樣的,這樣就造成了資源的極度浪費
解決方案
針對第一個問題,做出的改進如下

1 function CreatePerson(name , sex){ 2 3 //相當於這邊有 4 // var this = new Object(); 5 //添加屬性 6 this.name = name; 7 this.sex = sex; 8 9 //添加方法 10 this.showName = function () { 11 alert(this.name); 12 }; 13 this.showSex = function () { 14 alert(this.sex); 15 }; 16 //這邊有return this; 17 }
這個時候生成的實例對象會自動包含一個constructor屬性,指向它們的構造函數
當然還可以使用instanceof來驗證實例對象是否屬於原型對象
針對第二個問題,我們可以使用prototype(原型),Javascript規定,每一個構造函數都有一個prototype屬性,指向另一個對象。這個對象的所有屬性和方法,都會被構造函數的實例繼承。這意味着,我們可以把那些不變的屬性和方法,直接定義在prototype對象上。這很像CSS中的class,可以給一堆對象加上相同的屬性或方法。主要是用來添加一些系統不支持的方法或函數

1 <script> 2 function CreatePerson(name , sex){ 3 //添加屬性 4 this.name = name; 5 this.sex = sex; 6 } 7 //添加共用方法 8 CreatePerson.prototype.showName = function () { 9 alert(this.name); 10 }; 11 CreatePerson.prototype.showSex = function () { 12 alert(this.sex); 13 }; 14 15 var p1 = new CreatePerson('leo' , 'male'); 16 var p2 = new CreatePerson('shawn' , 'male'); 17 p1.showName(); 18 p1.showSex(); 19 20 alert(p1.showName == p2.showName); 21 </script>
這個時候我們會發現最后的輸出是true,這時候用的都是同一個內存地址,指向了prototype對象,內存的使用效率就變高。
最后關於一個優先級的問題

1 <script> 2 Array.prototype.a = 12; //給Array類添加公共屬性a = 12; 3 var arr = [1,2,3]; 4 alert(arr.a); //12 5 6 arr.a = 5; //給由Array類所創造的對象arr添加重名屬性a 7 alert(arr.a); // 5 8 9 delete arr.a; //刪除arr對象的a屬性 10 alert(arr.a); //12 11 </script>
我們會發現這和CSS中內部樣式和行間樣式很相像,prototype添加的屬性相當於一個內部樣式 ,而對象的重名屬性相當於行間樣式 , 所以重名時對象的屬性優先級肯定是高於prototype所添加的屬性的。