ECMAScript中構造函數模式雖然好用,但也并非沒有缺點。使用構造函數的主要問題,就是每個方法都要在每個實例上重新創建一遍。在前面的例子中,personl和person2都有一個名為sayName()的方法,但那兩個方法不是同一個Function的實例。不要忘了——ECMAScript中的函數是對象,因此每定義一個函數,也就是實例化了一個對象。從邏輯角度講,此時的構造函數也可以這樣定義:
function Person(name,age,Job){
this.name=name;
this.age=age;
this.job=job;
this.name = new Function("alert(this.name)"); 南昌網絡公司技術人提示:與聲明函數在邏輯上是等到價的
}
從這個角度上來看構造函數,更容易明白每個Person實例都包含一個不同的Function實例(以顯示name屬性)的本質。如前所述,這兩個函數是不相等的,下面的代碼可以證明這一點:
alert(personl.sayName==Derson2.sayName); //false
然而,創建兩個完成同樣任務的Function實例的確沒有必要;況且有this對象在,根本不用在執行代碼前就把函數綁定到特定對象上面。因此,大可像下面這樣,通過把函數定義轉移到構造函數外部來解決這個問題:
function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.sayName = sayName; } function sayName(){ alert(this.name); } var personl=new Person("Nicholas",29,"Software Engineer")
var person2=new Person("Greg",27,"Doctor");
personl.sayName(); //"Nicholas"
person2.sayName(); //"Greg"
alert(personl instanceof Object);//true
alert(personl instanceof Person);//true
alert(person2 instanceof Obj ect);//true
alert(person2 instanceof Person);//true
alert(personl.constructor==Person); //true
alert(person2.constructor==Person); //true
alert(personl.sayName==person2.sayName); //true
在這個例子中,我們把sayName()函數的定義轉移到了構造函數外部。而在構造函數內部,我們將sayName屬性設置成等于全局的sayName函數。這樣一來,由于sayName包含的是一個指向函數的指針,因此personl和person2對象就共享了在全局作用域中定義的同一個sayName()函數。這樣做確實解決了兩個函數做同一件事的問題,可是新問題又來了:在全局作用域中定義的函數實際上只能被某個對象調用,這讓全局作用域有點名不副實。而更讓人無法接受的是:如果對象需要定義很多方法,那么就要定義很多個全局函數,于是我們這個自定義的引用類型就絲毫沒有封裝性可言了,對于南昌建站公司技術人員來講,這個理解有點難度,但結合實例,通過實例操作應該不成問題.
好在,這些問題可以通過使用原型模式來解決。
本文僅限內部技術人員學習交流,不得作于其他商業用途.文章出自:南昌網站建設公司-百恒網絡 http://www.527701.com 如轉載請注明出處!