Javascript繼承的最佳實務,javascript最佳實務

來源:互聯網
上載者:User

Javascript繼承的最佳實務,javascript最佳實務

什麼是繼承?

繼承是物件導向最顯著的一個特性。繼承是從已有的類中派生出新的類,新的類能吸收已有類的資料屬性和行為,並能擴充新的能力。


在Javascript 中 沒有 類的概念, 它是通過建構函式來產生 對象,

建構函式 就是一個普通的函數,通常當函數名 為 大寫開頭的,我們認為是建構函式,否則 就是普通的方法。

function A() {    this.name = 'A Class instance';}function m1() {}

既然 Javascript 是 通過建構函式來產生 對象,那我們怎麼定義它的 屬性、方法呢?

var a1 = new A();  是新建立一個A類對象,預設情況下,在建構函式中,使用this指向的是 新建立的對象;


而Javascript的對象屬性 可以 晚綁定,即

var obj = {};obj.name = 'obj1';obj.say = function say() {    console.log(this.name);}
可以先產生對象,在需要增加屬性時, 通過 obj.屬性名稱  或 obj['屬性名稱']  來添加屬性。

所以我們在建構函式中 使用 this.屬性名稱 來 定義產生的 對象 的 屬性和方法。


function A() {    this.name = 'A Class instance';    this.say = function() {        console.log('Hi,I am ' + this.name);    }}var a1 = new A();var a2 = new A();a1.say(); // Hi,I am A Class instancea2.say(); // Hi,I am A Class instance

我們分析一下上面代碼,

建立了 a1,a2 對象,在建立a1,a2 對象的時候 都為其添加一個say()方法,而這2個對象的 say方法 完全一樣,

試想想 如果 建立n 個 A類對象,那是不是為這n個對象 添加一個say()方法,那是非常浪費記憶體。


所以在Javascript 中 引用了 prototype 原型的概念:

每一個建構函式都有一個prototype 對象,使用建構函式執行個體化一個對象,訪問這個對象屬性時,如果這個對象有該屬性,則返回,否則就會在該對象的建構函式的prototype 上找,直到找到就返回,否則返回的是undefined


來驗證一下:


 在上面代碼中,A建構函式中沒有定義say 方法,

但a1,a2 卻 能夠 調用say()方法,因為 A函數的prototype 預設指向的是 Object.prototype ;

此時記憶體中只儲存Object.prototype.say,而A產生的對象 是通過原型機制,一層一層往上找,然後調用的。


所以通過 prototype原型機制,我們可以實現代碼複用,和繼承。

A.prototype.say = function() {    console.log('Hi,I am ' + this.name);}function A() {    this.name = 'A Class instance';}var a1 = new A();var a2 = new A();a1.say(); // Hi,I am A Class instancea2.say(); // Hi,I am A Class instancefunction B() {    this.name = 'B Class instance';}B.prototype = new A();B.prototype.constructor = B;var b = new B();b.say();

分析一下上面代碼 執行結果:

我們定義了一個B類,並把他的prototype 指向 A的執行個體對象,

然後產生一個 b 對象,調用b對象 say() ,也輸出了內容。

這是為什麼呢?

訪問 b 對象屬性時, 如果不存在 ,就會在其 prototype 訪問,

就是 訪問a 對象的 prototype ,但a對象 prototype  預設 是 指向Object.prototype 的,

而我們在 Object.prototype 定義了say 方法,b 對象也能訪問 say()方法, 就好像b 繼承了 父類中的 屬性一樣。

這裡我們也可以看出,一旦 原型鏈 過長,會導致 訪問多個對象的prototype。

所以 在設計 的時候 應該 不超過 3層原型鏈,可以考慮其他方式。




Javascript 最佳的實踐:

A.prototype.say = function() {    console.log('Hi,I am ' + this.name);}function A() {    this.name = 'A Class instance';}
通過原型對象,添加方法,

通過建構函式 定義 對象的 屬性。


繼承還可以有很多種 實現方式, 比如 屬性的複製等等,應當靈活運用。



javascript繼承問題

呵呵 你的繼承還得學習下!! 給你最經典的一句:
代碼如下:
function WhitePerson (name){
this.name = name;
Person.call(this,name);
if(typeof WhitePerson._initialized=="undefined"){
WhitePerson.prototype.area = function (){
alert("中國"+this.name);
};
WhitePerson._initialized =true;
}

}
WhitePerson.prototype = new Person ();
好好想想為什麼吧!!
 
javascript繼承有哪兩種形式

Javascript的繼承在很多書裡面細緻的分了很多種類型和實現方式,大體上就是兩種:對象冒充、原型方式。這兩種方式各有優點和缺陷,這裡我給你先列舉出來,再從底層分析區別:

(一)對象冒充

function A(name){
this.name = name;
this.sayHello = function(){alert(this.name+” say Hello!”);};
}
function B(name,id){
this.temp = A;
this.temp(name); //相當於new A();
delete this.temp; //防止在以後通過temp引用覆蓋超類A的屬性和方法
this.id = id;
this.checkId = function(ID){alert(this.id==ID)};
}

當構造對象B的時候,調用temp相當於啟動A的建構函式,注意這裡的上下文環境中的this對象是B的執行個體,所以在執行A建構函式指令碼時,所有A的變數 和方法都會賦值給this所指的對象,即B的執行個體,這樣子就達到B繼承了A的屬性方法的目的。之後刪除臨時引用temp,是防止維護B中對A的類對象(注 意不是執行個體對象)的引用更改,因為更改temp會直接導致類A(注意不是類A的對象)結構的變化。

我們看到了,在Js版本更新的過程中,為了更方便的執行這種上下文this的切換以達到繼承或者更加廣義的目的,增加了call和apply函數。它們的 原理是一樣的,只是參數不同的版本罷了(一個可變任意參數,一個必須傳入數組作為參數集合)。這裡就以call為例子,解釋一下用call實現的對象冒充 繼承。

function Rect(width, height){
this.width = width;
this.height = height;
this.area = function(){return this.width*this.height;};
}
function myRect(width, height, name){
Rect .call(this,width,height);
this.name = name;
this.show = function(){
alert(this.name+” with area:”+this.area());
}
}

關於Call方法,官方解釋:調用一個對象的一個方法,以另一個對象替換當前對象。
call (thisOb,arg1, arg2…)

這也是一種對象冒充的繼承,其實在call方法調用的時候發生的事情也是上下文環境變數this的替換,在myRect函數體中this肯定是指向類 myRect對象的執行個體了,然而用這個this作為上下文環境變數調用名字叫Rect方法,即類Rect的建構函式。於是此時調用Rect時候對this 的賦值屬性和方法都實際上是對一個myRect的對象進行。所以說儘管call和apply並不是僅僅為了繼承而新增的方法,但用它們可以類比繼承。

對象冒充繼承就是這麼一回事,它可以實現多重繼承,只要重複做這一套賦值的流程就可以了。不過目前真正大規模使用得並不多,為什麼呢?因為它有一個明顯的 效能缺陷,這就要說道OO的概念了,我們說對象是成員+成員方法的集合,構造對象執行個體的時候,這些執行個體只需要擁有各自的成員變數就可以了,成......餘下全文>>
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.