JS中的類很難嗎张肾?

什么是Class 類芭析?

MDN上說(shuō):類定義對(duì)象的特征。它是對(duì)象的屬性和方法的模板定義吞瞪。
簡(jiǎn)單說(shuō)馁启,“類”是生產(chǎn)對(duì)象的模板,通過(guò)類這個(gè)模板芍秆,可以毫不費(fèi)勁地生產(chǎn)出無(wú)數(shù)個(gè)一樣的對(duì)象惯疙,而不用通過(guò)一次次的定義去聲明對(duì)象。而這些對(duì)象妖啥,因?yàn)榫哂幸粯拥膶傩悦沟摺⒁粯拥姆椒ǎ詫⑦@些對(duì)象歸為一個(gè)“類”荆虱,就像將人類歸入人這一類一樣蒿偎。

JavaScript 的類

在es 6 出現(xiàn)之前,ECMAScript 標(biāo)準(zhǔn)中都是沒(méi)有類的官方規(guī)范的克伊,JavaScript 的類都是通過(guò)其他的方法來(lái)模擬定義酥郭。直到ES 6 標(biāo)準(zhǔn)的到來(lái),JavaScript 才擁有官方的定義類的方法愿吹。

定義類的方法

1. 構(gòu)造函數(shù)法

構(gòu)造函數(shù)法使用構(gòu)造函數(shù)來(lái)模擬“類”不从,使用 this 在構(gòu)造函數(shù)內(nèi)部指代實(shí)例對(duì)象。

function Person(){
    this.species = 'human'
}

定義一個(gè)構(gòu)造函數(shù)之后犁跪,使用 new 關(guān)鍵字來(lái)生成實(shí)例對(duì)象

let xxx = new Person
console.log(xxx)     // {species: 'human'}

像上面定義的構(gòu)造函數(shù) Person椿息,可以使用 new 關(guān)鍵字來(lái)生成無(wú)數(shù)個(gè) 擁有屬性 species = 'human' 的對(duì)象。
然而坷衍,使用這種方法構(gòu)造對(duì)象寝优,當(dāng)構(gòu)造對(duì)象的數(shù)量太多時(shí),會(huì)極大地消耗內(nèi)存枫耳,所以JavaScript提供了函數(shù)的prototype屬性來(lái)節(jié)約內(nèi)存乏矾。

function Person(){

}

Person.prototype.species = 'human'

let xxx = new Person()
console.log(xxx)   // {}

可以看到,使用 Person 的prototype屬性定義對(duì)象的公共屬性 species迁杨,依然可以生成一個(gè)對(duì)象钻心。然而生成的卻是一個(gè)空對(duì)象。那么species屬性去哪了铅协?
species屬性跑到了實(shí)例對(duì)象 xxx 的原型上了:

console.log(xxx.species)      // human
console.log(xxx.__proto__)    // {species:human,constructor:function}

通過(guò)構(gòu)造函數(shù)的prototype屬性捷沸,可以將實(shí)例對(duì)象的公共屬性集成到一個(gè)原型對(duì)象上面,節(jié)約內(nèi)存

構(gòu)造函數(shù)法同時(shí)還可以實(shí)現(xiàn)對(duì)象的自有屬性和自有方法

function Person(){

}

Person.prototype.species = 'human'

let xxx = new Person()
xxx.abc = "abc"
console.log(xxx)   // {abc:abc}

構(gòu)造函數(shù)通過(guò)將值以參數(shù)的形式傳入函數(shù)內(nèi)部狐史,使構(gòu)造出的實(shí)例對(duì)象具有不同的屬性值痒给。

function Person(name,age){
    this.name = name
    this.age = age
}

Person.prototype.species = 'human'

let xxx = new Person(‘xiao’,18)
console.log(xxx)   // {name:xiao,age:18}

那么说墨,使用構(gòu)造函數(shù)法模擬類的流程是:

function 構(gòu)造函數(shù)名(自有屬性值1,自有屬性值2,...){
    this.自有屬性1 = 自有屬性值1
    this.自有屬性2 = 自有屬性值2
}

構(gòu)造函數(shù)名.prototype.xxx = xxx  // 設(shè)置構(gòu)造函數(shù)的原型屬性
// 還可以直接往實(shí)例對(duì)象上添加自己的屬性

2. Object.create() 實(shí)現(xiàn)類

Object.create()語(yǔ)法

Object.create(proto[, propertiesObject])
參數(shù):

  • proto:新創(chuàng)建對(duì)象的原型對(duì)象
  • propertiesObject:新創(chuàng)建對(duì)象的屬性配置。(如:是否可枚舉苍柏、是否只寫(xiě)等)
    返回值:
  • 返回新創(chuàng)建的對(duì)象尼斧。

使用Object.create()模擬類,是將一個(gè)對(duì)象直接作為新創(chuàng)建對(duì)象的原型序仙,直接將原型植入新對(duì)象突颊。
在這種方法中,“類”就是一個(gè)對(duì)象潘悼,而不是函數(shù)律秃。

let Person = {
    species: 'human',
    walk: function(){},
    speak: function(){},
}

let xxx = Object.create(Person)
console.log(xxx)

上面這段代碼,以 Person 這個(gè)對(duì)象作為原型治唤,生成一個(gè)新的空對(duì)象 xxx棒动,xxx 的原型指向 Person。換言之宾添,對(duì)象 Person 被當(dāng)做了一個(gè)類船惨,創(chuàng)建新的對(duì)象。

Object.create()模擬類的缺陷:

  • 實(shí)例對(duì)象的屬性全部在同一個(gè)”類“對(duì)象上面缕陕,只能實(shí)例對(duì)象名.屬性名 = 屬性值手動(dòng)添加自有屬性和自有方法
  • 由于Object.create() 只是將創(chuàng)建的實(shí)例對(duì)象的原型綁定到一個(gè)”類“對(duì)象上面粱锐。一旦”類“對(duì)象發(fā)生改變,所有的實(shí)例對(duì)象的值都會(huì)改變扛邑。
  • 實(shí)例對(duì)象的共享數(shù)據(jù)全部綁定在”類“對(duì)象上面怜浅。

3. 極簡(jiǎn)主義法

極簡(jiǎn)主義法同樣使用一個(gè)對(duì)象作為”類“,在對(duì)象里面蔬崩,定義一個(gè)createNew方法來(lái)生成實(shí)例

let Person = {
    createNew: function(){},
}

createNew方法里面恶座,定義一個(gè)實(shí)例對(duì)象作為返回值

let Person = {
    createNew: function(){
        let person = {}
        person.species = "human"
        person.walk = function(){}
        person.speak = function(){}
        return person
    },
}

調(diào)用createNew方法,就可以得到一個(gè)新的對(duì)象

let xxx = Person.createNew()
console.log(xxx)  // {species: "human", walk: function, speak: function}

極簡(jiǎn)主義法的原理:使用一個(gè)對(duì)象作為原本沥阳,去復(fù)制完成另一個(gè)對(duì)象
事實(shí)上跨琳,極簡(jiǎn)主義法的原理概念與Object.create()極為類似,兩個(gè)的唯一區(qū)別是:極簡(jiǎn)主義法不會(huì)修改實(shí)例對(duì)象的原型桐罕,而Object.create()涉及到原型脉让。兩者之間的公共屬性共享全部是通過(guò)操作“原本”來(lái)實(shí)現(xiàn)。

4. ES 6 的 class 聲明

ES 6 的 class 不是一個(gè)全新的類繼承模型功炮,而是一個(gè)原有模型的語(yǔ)法糖溅潜。
ECMAScript2015 將 第一種:構(gòu)造函數(shù)法 給官方化,定義一個(gè) api 直接使用“類”死宣。本質(zhì)上伟恶, class 定義的“類”還是一個(gè)函數(shù)

class Person {
    constructor(name, age){
        this.name = name
        this.age = age
    }
    walk(){}
    speak(){}
}

let xxx = new Person('xiao',18)
typeof Person     // "function",Person 本質(zhì)上還是一個(gè)函數(shù)
console.log(xxx)   // {name: "xiao", age: 18}

用函數(shù)模擬一個(gè)類的過(guò)程(舉例)

假設(shè)現(xiàn)在在設(shè)計(jì)一款游戲碴开,需要生成許多小兵毅该,就需要一個(gè)生成小兵的類博秫。
使用函數(shù)來(lái)生成小兵

function createBing(id,hp){
    let bing = {}    //  創(chuàng)建一個(gè)空對(duì)象存儲(chǔ)小兵的屬性
    bing.id = id
    bing.hp = hp
    bing.attack = 5
    bing.walk= function(){console.log('walk')}
    return bing
}

此時(shí),調(diào)用函數(shù) createBing 就能生成一個(gè)具有4個(gè)屬性的小兵對(duì)象眶掌。
此時(shí)挡育,生成數(shù)量多的小兵時(shí),會(huì)重復(fù)創(chuàng)建 hp 和 walk 這兩個(gè)屬性朴爬,浪費(fèi)內(nèi)存即寒。JS 中有原型,可以將公共屬性綁定到原型上面召噩。

// 首先需要一個(gè)原型對(duì)象母赵,將公共屬性放到原型對(duì)象上面
bingPrototype = {
    attack: 5,
    walk: function(){console.log('walk')}
}

function creareBing(id, hp){
    let bing = {}

    bing.__proto__ = bingPrototype // 將原型屬性綁定到生成的對(duì)象上面

    bing.id = id
    bing.hp = hp

    return bing
}

此時(shí),調(diào)用 createBing 函數(shù)可以生成一個(gè)具有 id 和 hp 兩個(gè)屬性的小兵對(duì)象具滴,attack 和 walk 被綁定到原型上面凹嘲,所有小兵對(duì)象共享。

由于__proto__不是標(biāo)準(zhǔn)規(guī)范构韵,所以使用另一個(gè)符合規(guī)范的方法周蹭,使用函數(shù)的 prototype 屬性和new關(guān)鍵字。
將實(shí)例對(duì)象的全部共有屬性綁定到生成實(shí)例對(duì)象的函數(shù)的prototype屬性上面疲恢,再用new關(guān)鍵字生成實(shí)例凶朗,可以直接將原型綁定到實(shí)例對(duì)象上。

function createBing(id, hp){
    this.id = id 
    this.hp = hp
}

createBing.prototype = {
    construcotr: createBing, // constrctor 是 prototype 的默認(rèn)屬性显拳,此寫(xiě)法會(huì)覆蓋棚愤,所以要重新賦值
    attack: 5,
    walk: function(){console.log('walk')}
}

至此,利用函數(shù)的prototypenew關(guān)鍵字萎攒,實(shí)現(xiàn)了用函數(shù)模擬類的目的遇八。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市耍休,隨后出現(xiàn)的幾起案子刃永,更是在濱河造成了極大的恐慌,老刑警劉巖羊精,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件斯够,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡喧锦,警方通過(guò)查閱死者的電腦和手機(jī)读规,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)燃少,“玉大人束亏,你說(shuō)我怎么就攤上這事≌缶撸” “怎么了碍遍?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵定铜,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我怕敬,道長(zhǎng)揣炕,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任东跪,我火速辦了婚禮畸陡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘虽填。我一直安慰自己丁恭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布斋日。 她就那樣靜靜地躺著涩惑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪桑驱。 梳的紋絲不亂的頭發(fā)上竭恬,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音熬的,去河邊找鬼痊硕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛押框,可吹牛的內(nèi)容都是我干的岔绸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼橡伞,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼盒揉!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起兑徘,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤刚盈,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后挂脑,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體藕漱,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年崭闲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了肋联。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡刁俭,死狀恐怖橄仍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤侮繁,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布氓奈,位于F島的核電站,受9級(jí)特大地震影響鼎天,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜暑竟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一斋射、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧但荤,春花似錦罗岖、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至纺非,卻和暖如春哑了,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背烧颖。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工弱左, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人炕淮。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓拆火,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親涂圆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子们镜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • ??面向?qū)ο螅∣bject-Oriented模狭,OO)的語(yǔ)言有一個(gè)標(biāo)志,那就是它們都有類的概念踩衩,而通過(guò)類可以創(chuàng)建任意...
    霜天曉閱讀 2,109評(píng)論 0 6
  • 函數(shù)和對(duì)象 1胞皱、函數(shù) 1.1 函數(shù)概述 函數(shù)對(duì)于任何一門語(yǔ)言來(lái)說(shuō)都是核心的概念。通過(guò)函數(shù)可以封裝任意多條語(yǔ)句九妈,而且...
    道無(wú)虛閱讀 4,566評(píng)論 0 5
  • 終于反砌,第一次在沒(méi)有司機(jī)的陪伴下。我自己和一個(gè)孕媽媽上路了萌朱! 然后宴树,嗯,其實(shí)就獨(dú)自開(kāi)了2公里晶疼,但是我最終還是牛噠噠的...
    笑莉說(shuō)閱讀 159評(píng)論 2 4
  • 我對(duì)濟(jì)南酒贬,可謂是第二故鄉(xiāng)又憨,除了自小生活的家鄉(xiāng)外,這里承載我四年的記憶锭吨,還有一群同學(xué)和朋友蠢莺,雖然我沒(méi)有老朋友,老同學(xué)...
    yariel閱讀 237評(píng)論 0 2
  • Considerations for Styling a Modal 原文地址modal,dialog,彈出層零如,會(huì)...
    Quilljou閱讀 501評(píng)論 0 0