Prototype的使用方式
Prototype(原型)是Javascript中實現對象繼承的基礎方式,使用方式為 [function].prototype = [object1]
[function]可認為相當於type/class,這樣可以使該類型的所有對象繼承[object1]中所有Public的屬性和方法。在這裡public的意思是使用了this.xxx。
先看以下例子
View Code
function Person() {
this.fullName = "Unknown";
this.sex = "Male";
this.speek = function(){
console.log(this.fullName + " is speeking");
}
}
function Staff() {
this.id = 1001;
this.title = "Developer";
}
Staff.prototype = new Person();
var s1 = new Staff();
console.log(s1.sex); //==> Male
s1.speek(); //==> Unknown is speeking
* 注: console.log的結果可以在瀏覽器開發人員工具/Firebug中的Console(控制台)中查看
通過指定Staff.prototype = new Person(), Staff類型的對象s1獲得了Person的屬性和方法。
Prototype的原理及實現方式
絕大多數的javascript對象都有原型對象,這些原型對象的應用形成一條“原型鏈”,鏈的盡頭是Object.prototype。當調用對象的某屬性或方法時,js引擎現在當前對象中尋找,找不到的話就會尋找其原型對象,如此上溯直到到達Object.prototype。我們所熟知的toString,valueOf等方法正是定義在Object.prototype中,因此所有js對象都通過繼承獲得這些方法。
在Chrome和Firefox裡,原型對象可以通過對象的屬性"__proto__"訪問,該屬性實際上指向對應類型的”prototype”屬性,即[object].__proto__ == [function].prototype。
在未指定繼承狀態下,每一個對象都具有一個預設的__proto__對象,而該__proto__的上一級原型對象為Object.prototype.
當指定Staff繼承自Person之後,__proto__屬性會指向personObj,原型鏈也會隨之變化
支援帶參數的建構函式
在第一點的代碼例子中,考慮建構函式帶參數的情況。
View Code
function Person(fullName, sex) {
this.fullName = fullName || "Unknown";
this.sex = sex || "Male";
this.speek = function(){
console.log(this.fullName + " is speeking");
}
}
function Staff(id, title, fullName, sex) {
this.id = id || 1001;
this.title = title || "Developer";
}
Staff.prototype = new Person();
var s1 = new Staff(99, "Manager","Eva", "Female");
console.log(s1.fullName); //==> Unknown
發現通過new Staff(…)無法對fullName和sex賦值,因為在指定繼承關係的時候並沒有把參數傳進Person的建構函式中。要解決此問題需要在Staff中將參數傳進Person,答案就是改變__prop__屬性。
View Code
function Person(fullName, sex) {
this.fullName = fullName || "Unknown";
this.sex = sex || "Male";
this.speek = function(){
console.log(this.fullName + " is speeking");
}
}
function Staff(id, title, fullName, sex) {
if(this.__proto__){ //For Firefox, Chrome
this.__proto__ = new Person(fullName, sex);
}else{ //For IE
Person.call(this,fullName, sex);
}
this.id = id || 1001;
this.title = title || "Developer";
}
Staff.prototype = new Person();
var s1 = new Staff(99, "Manager","Eva", "Female");
console.log(s1.fullName); //==> Eva
IE不支援__prop__屬性,可以使用call/apply方法,該方法將帶參數地調用Person()方法,並且將this作為Person()方法的當前對象。
這種做法所有瀏覽器都支援,所以通常直接使用call/apply即可,上述例子只是為說明__proto__屬性的作用。