前端的那些事(七):面向委托編程到es6的class(拋棄prototype)

前言

??這個(gè)概念是在js小黃書(shū)《你不知道的js》中了解到的商膊,面向?qū)ο笾心7隆邦悺钡臑E用導(dǎo)致代碼苦澀難懂饶囚,所以可以通過(guò)關(guān)聯(lián)委托的方式讓代碼更清晰易懂帕翻。
??es6的class類出現(xiàn)后,真正規(guī)范了類的使用萝风,而且簡(jiǎn)單易懂嘀掸。所以本文的意義在于了解一種好的設(shè)計(jì)理念,也可讓自身也具有創(chuàng)新能力规惰,寫(xiě)出更優(yōu)雅的代碼睬塌。

面向?qū)ο缶幊?/h1>

其根本在于模仿類,我們這里寫(xiě)一個(gè)寄生組合繼承歇万,也是es6的class的設(shè)計(jì)思想異曲同工揩晴。


function Parent(name, age) {
  this.name = name;
  this.age = age;
}

Parent.prototype.myName = function() {
  return this.name;
};

Parent.prototype.myAge = function() {
  return this.age;
};

function Child(name, age, sex) {
  Parent.call(this, name, age);
  this.sex = sex;
}
// 將Child.prototype關(guān)聯(lián)到Parent.prototype上
Child.prototype = Object.create(Parent.prototype);
 // var F = function() {};
 // F.prototype = Parent.prototype;
 // Child.prototype = new F();

// 如果此時(shí)要使用到Child.constructor, 手動(dòng)重置一下此屬性,使其指到Bar上贪磺。
Child.prototype.contructor = Child;

Child.prototype.mySex = function() {
  return this.sex;
};

var c = new Child('tony', '16', '男');
console.log(c.myName()); // tony
console.log(c.mySex()); // 男

這里有兩個(gè)硫兰,我需要強(qiáng)調(diào)一下:

  • Object.create原理
function objectCreate (obj) {
  var F = function() {};
  F.prototype = obj;
  return new F();
}

在上述寄生組合繼承中,就是下面注釋掉的代碼寒锚。

  • contructor丟失問(wèn)題
    當(dāng)你這么使用Child.prototype = ...劫映,直接等于就會(huì)讓contructor丟失违孝。原因是Child.prototype.contructor === Child ,也就是說(shuō)contructor是函數(shù)自帶的。所以需要重新指向泳赋。

面向委托設(shè)計(jì)

這里呢雌桑,我們將prototype去掉,直接通過(guò)Object.create方法摹蘑,構(gòu)建對(duì)象之間的關(guān)系筹燕。

var Parent = {
  initParent: function(name, age) {
    this.name = name;
    this.age = age;
  },
  myName: function() {
    return this.name;
  },
};

// 創(chuàng)建Child轧飞,并委托Parent的屬性
var Child = Object.create(Parent);

Child.initChild = function(name, age, sex) {
  this.initParent(name, age);
  this.sex = sex;
};
Child.mySex = function() {
  return this.sex;
};

var c = Object.create(Child);

c.initChild('tony', '16', '男');
console.log(c.myName()); // tony
console.log(c.mySex());  // 男

通過(guò)Object.create繼承父類的屬性和方法衅鹿,但這里還是有幾點(diǎn)不優(yōu)雅的問(wèn)題。

  • Parent對(duì)象寫(xiě)法比較優(yōu)雅过咬,可是Child的方法不能直接用對(duì)象方法大渤,只能Child.initChild的方法,不然會(huì)丟失父類方法掸绞。(原因就是Child={}這種寫(xiě)法本身就是重新賦值了)
  • 還是有煩人的Object.create進(jìn)行繼承泵三。

為了足夠優(yōu)雅和使用,es6推出class類的概念衔掸。

es6的class編程

class Parent {
  constructor(name, age) { // 初始化屬性
    this.name = name;
    this.age = age;
  }

  myName() {
    return this.name;
  }
}

class Child extends Parent {
  constructor(name, age, sex) {
    super(name, age); // 用super調(diào)用父類的構(gòu)造方法! 類似Parent.call(this, name, age)烫幕,但是this指的是子類的實(shí)例
    this.sex = sex;
  }

  mySex() {
    return this.sex;
  }
}

var c = new Child('tony', '16', '男');
console.log(c.myName()); // tony
console.log(c.mySex()); // 男

父子類完全可以用同樣的優(yōu)雅方法了;constructor里面設(shè)置初始化值敞映,與constructor同級(jí)的是方法较曼,取代了prototypesuper方法就是類似Parent.call調(diào)用父類構(gòu)造方法振愿,但是this指的是子類的實(shí)例(es5this指的是父類的實(shí)例)捷犹,不過(guò)es6做的更好,想繼承必須調(diào)用不然報(bào)錯(cuò)冕末,避免我們忘記萍歉。

??Class作為構(gòu)造函數(shù)的語(yǔ)法糖,同時(shí)有 prototype屬性和__proto__屬性档桃,因此同時(shí)存在兩條繼承鏈枪孩。(有點(diǎn)難理解,想清晰了解prototype__proto__的區(qū)別藻肄,請(qǐng)看https://blog.csdn.net/lc237423551/article/details/80010100
??簡(jiǎn)單來(lái)說(shuō)呢蔑舞,你只能看到__proto__,但是這個(gè)__proto__分兩種仅炊,一種是你繼承的斗幼,一種是你prototype創(chuàng)建的。第一種表示類的繼承抚垄,指向父類蜕窿;第二種表示類的實(shí)例繼承谋逻,指向類的prototype

  • 子類__proto__屬性桐经,表示類的繼承毁兆,總是指向父類。
  • 子類prototype屬性阴挣,表示類的實(shí)例的繼承臼寄,類的實(shí)例的__proto__屬性指向類的prototype屬性。

特性和寄生組合繼承特性一致薄霜,所以類的繼承可以看做是寄生組合繼承的語(yǔ)法糖牧牢,但是實(shí)現(xiàn)方式完全不同,思想是一致的誓沸。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末梅桩,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子拜隧,更是在濱河造成了極大的恐慌宿百,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件洪添,死亡現(xiàn)場(chǎng)離奇詭異垦页,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)干奢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)痊焊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人律胀,你說(shuō)我怎么就攤上這事宋光。” “怎么了炭菌?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵罪佳,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我黑低,道長(zhǎng)赘艳,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任克握,我火速辦了婚禮蕾管,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘菩暗。我一直安慰自己掰曾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布停团。 她就那樣靜靜地躺著旷坦,像睡著了一般掏熬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上秒梅,一...
    開(kāi)封第一講書(shū)人閱讀 49,079評(píng)論 1 285
  • 那天旗芬,我揣著相機(jī)與錄音,去河邊找鬼捆蜀。 笑死疮丛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的辆它。 我是一名探鬼主播誊薄,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼娩井!你這毒婦竟也來(lái)了暇屋?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤洞辣,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后昙衅,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體扬霜,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年而涉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了著瓶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡啼县,死狀恐怖材原,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情季眷,我是刑警寧澤余蟹,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站子刮,受9級(jí)特大地震影響威酒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜挺峡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一葵孤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧橱赠,春花似錦尤仍、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鲤嫡。三九已至,卻和暖如春绑莺,著一層夾襖步出監(jiān)牢的瞬間暖眼,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工纺裁, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留诫肠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓欺缘,卻偏偏與公主長(zhǎng)得像栋豫,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子谚殊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345