有關javaScript物件導向和原型筆記
javaScript是一種比較特殊的語言,ECMAScript中沒有類的概念,跟其他物件導向的語言有一定的區別,它的對象也與基於類的語言中的對象有所不同,嚴格來說,javascript對象是一組沒有特定順序的值,對象的每個屬性或方法都有一個名字,而每個名字都映射到一個值。每個對象都是基於一個參考型別的建立的。
建立自訂對象的最簡單的方式就是建立一個Object的執行個體,然後再為其添加屬性和方法,如:
var box = new Object(); //建立對象box.name1 = 'Lee'; //添加屬性box.age = 100; //box.run = function () { return this.name1 + this.age //this表示當前範圍下對象
不足:使用同一個介面建立很多個物件,會產生很多重複代碼。
原廠模式:
在ECMAScript中無法建立類,開發人員就想出了另外一種方法,用一種函數來封裝以特定介面建立對象的細節,如:
function createPerson(name,age,job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ alert(this.name); } return o; } var person1 = createPerson('lilei',29,'Software Engineer'); var person2 = createPerson('Greg',27,'Doctor'); person1.sayName(); person2.sayName(); alert(typeof person1); alert(typeof person2);
函數creatPerson()能夠根據接受的參數來構建一個包含所有必要資訊的Person對象,可以無數次低調用這個函數,而每次它都返回一個包含三個屬性的一個方法的對象。原廠模式雖然解決了建立多個類型對象的問題,但卻沒有解決對象識別的問題。
建構函式模式
function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(this.name); }; } var person1 = new Person('lilei',29,'Software Engineer'); var person2 =new Person('Greg',27,'Doctor'); person1.sayName(); person2.sayName(); alert( person1 instanceof Object); alert( person2 instanceof Person);
在這個例子當中,Person()函數取代了createPerson()函數。同時注意到跟createPerson()函數的區別:
沒有顯式地建立對象;
直接將屬性和方法賦給了this對象;
沒有return 語句;
構成方法首個字母大寫;
建構函式的的問題也有,就是每個方法都要在每個執行個體上重新建立一遍,
組合使用建構函式模式和原型模式
建立自訂類型常見的方式是組合使用建構函式模式和原型模式。建構函式模式用於定義執行個體屬性,而原型模式用定義方法和共用屬性,從而每個執行個體都會有 自己的一份執行個體屬性的副本,但同時又共用著對方的方法的引用,
function Person(name,age,job){ this.name =name; this.age = age; this.friends = ["Shelpy","Court"]; } Person.prototype = { constructor:Person, sayName:function(){ alert(this.name) } } var person1 = new Person('lilei',29,'Software Engineer'); var person2 = new Person('Greg',27,'Doctor'); person1.friends.push("Van"); alert(person1.friends); alert(person2.friends); alert(person1.friends === person2.friends); alert(person1.sayName === person2.sayName);
在這個例子中,執行個體屬性都是在建構函式中定義的,而由所有執行個體共用的屬性consructor和方法sayName()則是在原型中定義的,當修改了person1.friends時,並不會影響到person2,.friends,因為它們引用了不同的數組。