JavaScript 常被描述為一種基於原型的語言 (prototype-based language)——每個對象擁有一個原型對象,對象以其原型為模板、從原型繼承方法和屬性。原型對象也可能擁有原型,並從中繼承方法和屬性,一層一層、以此類推。這種關係常被稱為原型鏈 (prototype chain) ...
-
JavaScript 常被描述為一種基於原型的語言 (prototype-based language)——每個對象擁有一個原型對象,對象以其原型為模板、從原型繼承方法和屬性。原型對象也可能擁有原型,並從中繼承方法和屬性,一層一層、以此類推。這種關係常被稱為原型鏈 (prototype chain),它解釋了為何一個對象會擁有定義在其他對象中的屬性和方法。準確地說,這些屬性和方法定義在Object的構造器函數(constructor functions)之上的
prototype
屬性上,而非對象實例本身。Java通過首先定義“類”,此後創建對象實例時,類中定義的所有屬性和方法都被覆制到實例中,在 JavaScript 中並不如此複製——而是在對象實例和它的構造器之間建立一個鏈接(它是__proto__屬性,是從構造函數的prototype
屬性派生的),之後通過上溯原型鏈,在構造器中找到這些屬性和方法,所以JavaScript是基於原型鏈繼承的。 - JavaScript面向對象中需要註意以下幾點:
(1)JavaScript中除了基本類型外其他都可以看做對象,而每個實例對象都有一個_proto_屬性,它指向構造這個實例對象的構造函數的prototype屬性。
(2)所有的函數對象都擁有一個特殊的屬性prototype屬性,該屬性指向實例對象的原型對象,經常使用原型對象來實現繼承。
(3)prototype是一個原型對象,所以它有一個屬性_proto_,這個值指向構造出這個原型對象的構造函數的prototype屬性。它還有另外一個屬性constructor,它指向指向該原型對象對應的構造函數。
-
js中的原型繼承:首先我們定義了一個構造函數Person,有
first, last, age, gender, interests等屬性,所有的方法都定義在構造器的prototype上,如greeting方法。
function Person(first, last, age, gender, interests) {
this.name = {
first,
last
};
this.age = age;
this.gender = gender;
this.interests = interests;
};
Person.prototype.greeting = function() {
alert('Hi! I\'m ' + this.name.first + '.');
};
現在我們想要創建一個Teacher類,這個類會繼承Person類,同時包括
- 一個新的屬性
subject
——這個屬性包含了教師教授的學科。 - 一個被更新的
greeting()
方法,這個方法打招呼聽起來比一般的greeting()
方法更正式一點——對於一個教授一些學生的老師來說。
這裡我們需要用到call()函數。這個函數允許您調用一個在這個文件里別處定義的函數。第一個參數指明瞭在您運行這個函數時想對“this
”指定的值,也就是說,您可以重新指定您調用的函數里所有“this
”指向的對象。其他的變數指明瞭所有目標函數運行時接受的參數。
Teacher.prototype.greeting = function() {
var prefix;
if(this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') {
prefix = 'Mr.';
} else if(this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') {
prefix = 'Mrs.';
} else {
prefix = 'Mx.';
}
alert('Hello. My name is ' + prefix + ' ' + this.name.last + ', and I teach ' + this.subject + '.');
};
之後我們需要讓Teacher類繼承Person類中的所有方法:
Teacher.prototype = Object.create(Person.prototype);
我們通過Object.create(Person.prototype)實現了Teacher類繼承Person類的方法,但是此時Teacher.prototype.constructor指向的是Person方法,這樣是有問題的,所以我們還需要:
Teacher.prototype.constructor = Teacher;
這樣就將
Teacher.prototype.constructor 指向了 Teacher 方法本身。
現在我們還剩最後一項工作,在構造函數Teacher()
上定義一個新的函數greeting()
。最簡單的方法是在Teacher的原型上定義它—把以下代碼添加到您代碼的底部:
Teacher.prototype.greeting = function() {
var prefix;
if(this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') {
prefix = 'Mr.';
} else if(this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') {
prefix = 'Mrs.';
} else {
prefix = 'Mx.';
}
alert('Hello. My name is ' + prefix + ' ' + this.name.last + ', and I teach ' + this.subject + '.');
};