物件導向的Javascript – 通過原型(Prototype)實現繼承

來源:互聯網
上載者:User
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__屬性的作用。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.