在JS中可使用function關鍵字來定義一個類。設計模式
添加類的成員,在函數內經過this指針引用的變量或者方法都會成爲類的成員。函數
function class1(){ var s = "abc"; this.p1=s; this.Method1=function(){ alert("this is a test method"); } } var obj1=new class1();// //在JS中,function自己的定義就是類的構造函數。 /* * new 建立對象的過站 * 1)當解釋器遇到new操做符時便建立一個空對象; * 2)開始運行class1這個函數,並將其中的this指針都指向這個新建的對象; * 3)由於當給對象不存在的屬性賦值時,解釋器就會爲對象建立該屬性,例如在class1中,當執行到this.p1=s這條語句時, * 就會添加一個屬性p1,並把變量s的值賦給它,這樣函數執行就是初始化這個對象的過程,即實現構造函數的做用。 * 4)當函數執行完後,new操做符就返回初始化後的對象。 * * 經過這整個過程,JS中就實現了面向對象的基本機制。因而可知,在JS中,function的定義實際上就是實現一個對象的構造器, * 是經過函數來完成的,這種方式的缺點: * 1)將全部的初始化語句,成員定義都放到一塊兒,代碼邏輯不夠清晰,不易實現複雜的功能。 * 2)每建立一個類的實例,都要執行一次構造函數。構造函數中定義的屬性和方法總被重複的建立。 * 例如:this.Method1=function(){ alert("this is a test method"); } 這裏的Method1每建立一個class1的實例,都會被建立一次,形成了內存的浪費。(prototype對象能夠解決相關缺點。) */
function class1(){ this.prop=1; }; class1.prototype.showProp=function(){//使用函數的prototype屬性給類定義新成員 alert(this.prop); } var obj1=new class1(); obj1.showProp();//調用經過prototype原型對象定義的showProp方法 /* * prototype是一個js對象,能夠爲prototype對象添加,修改,刪除方法和屬性。從而爲一個類添加成員定義。 * 瞭解了函數的prototype對象,在來看new的執行過程: * 1)建立一個新的對象,並讓this指針指向它。 * 2)將函數的prototype對象的全部成員都賦給這個新對象 * 3)執行函數體,對這個對象進行初始化操做 * 4)返回1中建立的對象 * * 和以前new的執行過程相比,多了用prototype來初始化對象的過程,這也和prototype的字面意思相符,它是所對應類的 * 實例的原型。這個初始化過程發生在函數體(構造器)執行以前,因此能夠在函數體內調用prototype中定義的屬性和方法! * */ function class2(){ this.prop=1; this.showProp(); }; class2.prototype.showProp=function(){//使用函數的prototype屬性給類定義新成員 alert(this.prop); } var obj2=new class2(); //PS:原型對象的定義必須在建立類實例的語句以前,不然它將不會起做用。 //prototype對象運用於設計類的成員,它是和一個類緊密相關的! //prototype還有一個重要的屬性:constructor,表示對該構造函數的引用. function class3(){ alert(123); } class3.prototype.constructor();//調用類的構造函數,等同於: class.prototype.constructor()==class1;
/* * 在JS中,因爲對象靈活的性質,在構造函數中也能夠爲類添加成員,在增長靈活性的同時,也增長了代碼的複雜度。 *爲例提供代碼的可讀性和開發效率,能夠採用這種定義成員的方式:使用prototype對象來替代,這樣function的定義就是類的 * 構造函數,符合傳統意義類的實現(類名和構造函數名是相同的)。 */ //第一種方式 function class1(){ //構造函數 }; class1.prototype.somePropety='sample'; class1.prototype.someMethod=function(){ // }; //以上這種方式很清晰,但每定義一個屬性或方法,都須要使用一次class1.prototype,不只代碼體積變大,並且易讀性不夠 //第二種方式(推薦) //進一步改善,可使用無類型對象的構造方法來指定prototype對象,從而實現類的成員定義 function class2(tt){ //構造函數 this.somePropety=tt; } class2.prototype={//經過指定prototype對象來實現類的成員定義 somePropety:'sample', someMethod:function(){ //... } //anything alse } /* * 以上,很清晰的定義了class1,構造函數直接用類名來實現,而成員使用無類型對象來定義,以列表的方式實現了全部屬性和 * 方法,而且能夠在定義的同時初始化屬性的值。這也更像傳統意義面嚮對象語言中類的實現。只是構造函數和類的成員定義被 * 分爲兩個部分,這可當作JS中定義類的一個固定模式,這樣在使用時會更加容易理解。 * * 注意:在一個類的成員之間互相引用,必須經過this指針類進行,例如在上面例子中的someMethod方法中,若是使用屬性 * somePropety,必須經過this.somePropety的形式,由於在JS中每一個屬性和方法都是獨立的,它們經過this指針聯繫在一個 * 對象上!!! */