JavaScript 的繼承機制(圖文)
一、JavaScript的一些語言特性
1.當我們聲明一個函數時,實際上是定義了一個函數類型的對象。如下所示,下面三種方式定義函數對象結果是一樣的。
var func = function(){
//....define code goes there.
}
function func ()
{
// ...define code goes there.
}
var func = new Function(....); 而當我們使用它時,它會一次執行其內的代碼。
2. this 指針的作用。在函數的內部,函數的this指針的作用域是動態綁定的,即this 代表的作用域是 上面的func 變量的作用域。但是,當我們使用new func()時,此時會為函數 func 獨立出一塊內存區域,this 的作用域便是func自己的區域。
var func = function()
{
this.name = "louis";
this.age = 22;
}
func(); //此時函數運行后,在外部window 對象可以訪問name,age
var a = new func();// 此時的函數運行后,a.name,b,name. 總結:出現上面的情況是因為函數 是一個function 類型的對象,其中,內部定義的執行語句是不可識別的,都是以字符串的形式存儲在相應的區域,當我們調用它們的時候,即使用() 的時候,這時候的代碼才會被拿出來,在給定的一個作用域內解析并且執行。這就是所謂的動態綁定: 即只有在運行的情況下才知道其執行的上下文。
3.根據上面的函數的特性,我們現在定義了一個Person類 ,和一個Woman 類,由Woman類要繼承Person類,我們可以在Woman內,創建一個對Person 變量的一個引用,然后執行之,這時候函數執行的上下文是Woman內部,即Person函數執行后,Person 內部的變量、屬性自然隸屬于 Woman 創建的對象了.
function Person()
{
this.name="people";
this.speak = function(){
console.log("hello,Fellow");
}
}
// Woman要繼承Person類
function Woman()
{
this.birthe = function(){
console.log("brithing...");
}
} 這種繼承的方式,叫做 對象冒充。
function Woman()
{
//對象冒充方式,將函數Person動態在Woman內部執行
this.newMethod = Person;
this.newMethod();
delete this.newMethod;
this.birthe = function(){
console.log("birthing....");
}
} 二、繼承的方式介紹
1. 對象冒充(如上所述)
對象冒充可以實現多重繼承:
function ClassZ() {
this.newMethod = ClassX;
this.newMethod();
delete this.newMethod;
this.newMethod = ClassY;
this.newMethod();
delete this.newMethod;
} 上面的模式有個弊端,就是ClassX和ClassY 的屬性定義中,如果有重復的情況,則對于繼承者ClassZ而言,要看其繼承順序,后面的聲明繼承的類會覆蓋先聲明的類,即:ClassY的屬性和 ClassX重合的話,ClassY會覆蓋ClassX內的屬性。
以對象冒充為原理,JavaScript提供了兩個可以完成此繼承的的方法:apply(),call();
假設現在有對象a, 它要繼承 B中的屬性和方法,如下所示:
function B (words)
{
this.name="hello";
this.say= function(){
console.log(words);
};
}
var a = new Object();
//a 繼承B內的屬性。
B.call(a,"hello");
B.apply(a,new Array("hello")); 2. 原型模式
在我們現實生活中,經常聽到 某某東西出現了山寨貨,那所謂的山寨貨,則是以某個正品貨為原型造出來的東西,即是仿的。javascript 內的“原型”,和這個意思差不多,都是以某一對象作為參考,進行對象的創建。故而,我們在對象的創建時,如果需要以某一對象作為原型,則如下操作:
// 設定B 以A 為原型創建
function A()
{
this.attr1;
this.attr2;
this.method1();
///....
}
function B()
{
}
B.prototype = new A();
var b = new B();// 繼承A內所有的屬性 另外A 也可以以其它對象作為原型進行創建對象,由此,便組成了原型鏈:
使用原型繼承機制的一個弊端,就是B.prototype = new A(); A () 是不可以帶參數的。如果使用參數,則可以使用對象冒充。 function ClassA(sColor) {
this.color = sColor;
}
ClassA.prototype.sayColor = function () {
alert(this.color);
};
function ClassB(sColor, sName) {
ClassA.call(this, sColor);
this.name = sName;
}
ClassB.prototype = new ClassA();
ClassB.prototype.sayName = function () {
alert(this.name);
};

