亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

js類式繼承的具體實現方法

2019-11-20 21:20:25
字體:
來源:轉載
供稿:網友

在開始擺弄代碼之前,應該搞清楚使用繼承的目的和能帶來什么好處。一般來說,在設計類的時候,我們希望能減少重復性的代碼,并且盡量弱化類之間的耦合。而要做到這兩者都兼顧是很難的,我們需要根據具體的條件和環境下決定我們應該采取什么方法。根據我們對面向對象語言中繼承的了解,繼承會帶類直接的強耦合,但js由于其特有的靈活性,可以設計出強耦合和弱耦合,高效率和低效率的代碼。而具體用什么,看情況。

下面提供js實現繼承的三種方法:類式繼承,原型繼承,摻元類。這里先簡述類式繼承,后兩種在往后的隨便中簡述,請多多關注、指導,謝謝。

類式繼承。

js類式繼承的實現依靠原型鏈來實現的。什么是原型鏈?js中對象有個屬性prototy,這個屬性返回對象類型的引用,用于提供對象的類的一組基本功能。

貌似對prototype有印象,對了,我們經常這樣用代碼。

復制代碼 代碼如下:

var Person = function(){   
    this.name = "liyatang";
};
Person.prototype = {
    //可以在這里提供Person的基本功能
    getName : function(){
        return this.name;
    }
}

我們把類的基本功能放在prototype屬性里,表示Person這個對象的引用有XXX功能。

在理解原型后,需要理解下什么是原型鏈。在訪問對象的某個成員(屬性或方法)時,如果這個成員未見于當前對象,那么js會在prototype屬性所指的那個對象中查找它,如果還沒有找到,就繼續到下一級的prototype所指的對象中查找,直至找到。如果沒有找到就會返回undifined。

那么原型鏈給我們什么提示呢?很容易聯想到,原型鏈意味著讓一個類繼承另一個類,只需將子類的prototype設置為指向父類的一個實例即可。這就把父類的成員綁定到子類上了,因為在子類上查找不到某個成員時會往父類中查找。(以上這兩段用詞不嚴謹,只在用通俗易懂的言語描述)

下面我們需要個Chinese類,需要繼承Person類的name和getName成員。

復制代碼 代碼如下:

var Chinese = function(name, nation){
        //繼承,需要調用父類的構造函數,可以用call調用,this指向Chinese
    //使Person在此作用域上,才可以調用Person的成員
    Person.call(this,name);
    this.nation = nation;
};
Chinese.prototype = Person.prototype;
//這里不可和以前一樣,因為覆蓋掉了prototype屬性
//Chinese.prototype = {
//  getNation : function(){
//      return this.nation;
//  }
//};
//以后的方法都需要這樣加
Chinese.prototype.getNation = function(){
        return this.nation;
};

繼承關系就建立了,我們這樣調用它

復制代碼 代碼如下:

var c = new Chinese("liyatang","China");
alert(c.getName());// liyatang

于是類式繼承就這樣完成了。難道真的完成了嘛,用firebug在alert那里設斷點,會發現原來的Person.prototype被修改了,添加了getNation方法。

這是因為在上面的代碼Chinese.prototype = Person.prototype; 這是引用類型,修改Chinese同時也修改了Person。這本身就是不能容忍的,且使類之間形成強耦合性,這不是我們要的效果。

我們可以另起一個對象或實例化一個實例來弱化耦合性。

復制代碼 代碼如下:

//第一種
//Chinese.prototype = new Person();
//第二種
//var F = function(){};
//F.prototype = Person.prototype;
//Chinese.prototype = F.prototype;

這兩種方法有什么區別呢。在第二種中添加了一個空函數F,這樣做可以避免創建父類的一個實例,因為有可能父類會比較龐大,而且父類的構造函數會有一些副作用,或者說會執行大量的計算任務。所以力薦第二種方法。

到此,完了嘛,還沒有!在對象的屬性prototype下面有個屬性constructor,它保存了對構造特定對象實例的函數的引用。根據這個說法Chiese.prototype.constructor應該等于Chinese,實際上不是。

回憶之前在設置Chiese的原型鏈時,我們把Person.prototype 覆蓋掉了Chiese.prototype。所以此時的Chiese.prototype.constructor是Person。我們還需要添加以下代碼

復制代碼 代碼如下:

//對這里的if條件不需要細究,知道Chinese.prototype.constructor = Chinese就行
if(Chinese.prototype.constructor == Object.prototype.constructor){
    Chinese.prototype.constructor = Chinese;
}

整理全部代碼如下

復制代碼 代碼如下:

var Person = function(name){
    this.name = name;
};
Person.prototype = {
    getName : function(){
        return this.name;
    }
};

var Chinese = function(name, nation){
    Person.call(this,name);
    this.nation = nation;
};
var F = function(){};
F.prototype = Person.prototype;
Chinese.prototype = F.prototype;
if(Chinese.prototype.constructor == Object.prototype.constructor){
    Chinese.prototype.constructor = Chinese;
}
Chinese.prototype.getNation = function(){
        return this.nation;
};

var c = new Chinese("liyatang","China");
alert(c.getName());

如果可以把繼承的代碼放在一個函數里,方便代碼復用,最后整理代碼如下

復制代碼 代碼如下:

function extend(subClass,superClass){
    var F = function(){};
    F.prototype = superClass.prototype;
    subClass.prototype = new F();
    subClass.prototype.constructor = subClass;
    subClass.superclass = superClass.prototype; //加多了個屬性指向父類本身以便調用父類函數
    if(superClass.prototype.constructor == Object.prototype.constructor){
        superClass.prototype.constructor = superClass;
    }
}

var Person = function(name){
    this.name = name;
};
Person.prototype = {
    getName : function(){
        return this.name;
    }
};

var Chinese = function(name, nation){
    Person.call(this,name);
    this.nation = nation;
};
extend(Chinese, Person);
Chinese.prototype.getNation = function(){
        return this.nation;
};

var c = new Chinese("liyatang","China");
alert(c.getName());

發表后修改:

在一樓的評論下,我對那個extend函數又有新的看法。之前在討論如何設置原型鏈時提出了兩種方法

復制代碼 代碼如下:

//第一種
//Chinese.prototype = new Person();
//第二種
//var F = function(){};
//F.prototype = Person.prototype;
//Chinese.prototype = F.prototype;

雖然第二種減少了調用父類的構造函數這條路,但在設計Chinese類時用了Person.call(this,name);這里也相當于調用了父類的構造函數。

然而用第一種方法的話可以減少在Chinese中再寫Person.call(this,name);,這部分代碼在子類中往往會遺忘。不妨把這種功能代碼放在了extend里。就只寫

Chinese.prototype = new Person();也達到同樣的目的:耦合不強。

但遺忘的一點是,Chinese.prototype = new Person();這樣寫對嘛。答案是不對!很明顯 new Person()需要傳一個name參數的。我們不可能在extend函數里做這部分工作,只好在Chinese類里調用父類的構造函數了。這樣也符合面向對象的思路。

所以,還是力薦用第二種方法。

第一次這樣寫有關技術類的文章,基本是按自己的思路鋪展開來,難免會有一些沒有考慮到的地方和解釋的不清楚的地方,望留言反饋,謝謝。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
神马国产精品影院av| 菠萝蜜影院一区二区免费| 欧美精品一本久久男人的天堂| 亚洲电影天堂av| 日韩亚洲精品电影| 欧美电影在线观看完整版| 久久精品电影一区二区| 久久精品亚洲94久久精品| 精品国产一区二区在线| 理论片在线不卡免费观看| 庆余年2免费日韩剧观看大牛| 午夜精品蜜臀一区二区三区免费| 亚洲色图17p| 国产中文字幕亚洲| 午夜精品在线视频| 亚洲一级一级97网| 538国产精品一区二区免费视频| 日韩成人久久久| 亚洲国产高清自拍| 国产成人啪精品视频免费网| 尤物九九久久国产精品的分类| 狠狠躁18三区二区一区| 久久久亚洲网站| 国产精品1区2区在线观看| 欧美午夜xxx| 成人春色激情网| 91香蕉嫩草神马影院在线观看| 亚洲女人天堂av| 久久久久久av| 日韩在线视频中文字幕| 亚洲国产成人精品久久久国产成人一区| 久久精品成人一区二区三区| 亚洲无亚洲人成网站77777| 欧美亚洲视频在线观看| 久久99精品久久久久久琪琪| 78m国产成人精品视频| 91视频国产精品| 欧美高清理论片| 中文字幕少妇一区二区三区| 日韩精品中文字幕在线观看| 日韩a**中文字幕| 国产高清在线不卡| 中文字幕精品一区二区精品| 欧美日韩精品中文字幕| 69久久夜色精品国产69| 91精品在线播放| 国产精品第一页在线| 中文字幕亚洲欧美日韩高清| 久久久久久噜噜噜久久久精品| 亚洲一区二区三区久久| 欧美日韩成人精品| 欧美成aaa人片在线观看蜜臀| 在线日韩第一页| 国产亚洲成av人片在线观看桃| 国产成人一区二区三区| 国产欧美日韩专区发布| 性欧美办公室18xxxxhd| 日韩av片免费在线观看| 久久777国产线看观看精品| 国产精品亚洲欧美导航| 日韩在线观看视频免费| 日韩激情视频在线播放| 国产精品美女午夜av| 日韩精品视频在线观看免费| 亚洲免费视频观看| 91精品国产高清自在线看超| 高清欧美电影在线| 国产精品91在线观看| 正在播放国产一区| 在线免费看av不卡| 欧美激情中文字幕在线| 精品亚洲国产视频| 国产丝袜精品视频| 久久99精品久久久久久噜噜| 欧美性猛交99久久久久99按摩| 中文字幕一精品亚洲无线一区| 欧美性videos高清精品| 亚洲伊人一本大道中文字幕| 亚洲小视频在线观看| 国产a级全部精品| 97在线观看免费| 日韩国产精品视频| 色综合色综合久久综合频道88| 久久成人一区二区| 国产精品美女久久| 欧美精品久久一区二区| 亚洲网站视频福利| 日韩av片永久免费网站| 日韩女优人人人人射在线视频| 欧美成人免费一级人片100| 国产一区二区在线免费| 97av在线视频免费播放| 91久久久久久久一区二区| 精品视频在线播放色网色视频| 法国裸体一区二区| 欧美午夜视频在线观看| 久久久久国产一区二区三区| 国产精品久久久久久久7电影| 欧亚精品在线观看| 欧美性资源免费| 97久久精品人人澡人人爽缅北| 欧美性69xxxx肥| 日韩欧美福利视频| 亚洲人成人99网站| 成人黄色在线免费| 欧美日本啪啪无遮挡网站| 国产成人综合亚洲| 欧美专区第一页| 亚洲最大中文字幕| 国产美女高潮久久白浆| 久久亚洲精品一区二区| 亚洲美女性视频| 在线成人一区二区| 久久精品91久久香蕉加勒比| 国产欧美精品在线播放| 国产精品美女视频网站| 777777777亚洲妇女| 国产精品久久久久久久久久99| 久久久久久久国产精品视频| 国产网站欧美日韩免费精品在线观看| 国产精品欧美久久久| 在线午夜精品自拍| 亚洲网站视频福利| 久久九九热免费视频| 国产精品扒开腿做爽爽爽的视频| 欧美国产欧美亚洲国产日韩mv天天看完整| 精品网站999www| 91夜夜未满十八勿入爽爽影院| 亚洲免费中文字幕| 欧美在线观看网址综合| 国产精品h在线观看| 日韩av在线网| 欧美国产极速在线| 久久97精品久久久久久久不卡| 久久久av电影| 久久久伊人日本| 欧美一级电影在线| 国产综合视频在线观看| 欧美在线视频播放| 日韩精品视频在线免费观看| 亚洲男人天堂2023| 77777亚洲午夜久久多人| 精品女同一区二区三区在线播放| 亚洲视屏在线播放| 午夜精品久久久久久99热软件| 久久综合色影院| 亚洲精品国产美女| 91精品视频在线免费观看| 国产在线观看精品| 在线视频欧美性高潮| 精品久久久久久久久久久| 亚洲天堂av网| 亚洲国产欧美自拍| 日韩综合中文字幕| www.久久撸.com| 久久久国产视频| 国产精品丝袜一区二区三区| 亚洲女人被黑人巨大进入al| 成人福利网站在线观看| 91久久精品国产91久久性色| 国产日韩精品电影| 成人黄色影片在线| 亚洲欧美日韩中文在线| 日韩在线高清视频|