溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JavaScript 對(duì)象是什么

發(fā)布時(shí)間:2020-10-10 16:52:19 來(lái)源:億速云 閱讀:167 作者:小新 欄目:web開(kāi)發(fā)

小編給大家分享一下JavaScript 對(duì)象是什么,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!

這里我們繼續(xù)學(xué)習(xí)兩個(gè)比較重要的類型,就是 ObjectSymbol。我們主要講的是 Object,相對(duì) Object 來(lái)說(shuō) Symbol 只是一個(gè)配角。

關(guān)于對(duì)象這個(gè)概念大家非常早就會(huì)接觸到了,其實(shí)人大概在 5 歲的時(shí)候就會(huì)產(chǎn)生對(duì)象的抽象。很多時(shí)候我們看起來(lái)好像對(duì)象是我們學(xué)編程的時(shí)候才知道有面向?qū)ο?。但是從認(rèn)知的角度來(lái)說(shuō),應(yīng)該是比我們平時(shí)對(duì)數(shù)字中的值這個(gè)類型的認(rèn)知要早的多。所以歷史的角度也一直被評(píng)價(jià)為,對(duì)象是更貼近人類的自然思維的。

剛剛說(shuō)到我們從小時(shí)候就已經(jīng)產(chǎn)生了對(duì)象的概念了,那為什么說(shuō)從小就有呢?Object 在英文里其實(shí)它的意思是一個(gè)非常廣泛的東西,他是任何一個(gè)物體,可以是抽象的物體,也可以是一個(gè)實(shí)際的物體。但是在我們中文里,找不到一個(gè)合適的詞,可以代表保羅萬(wàn)物的詞來(lái)表達(dá) Object 的含義。所以在中文中我們就直接翻譯成 “對(duì)象”。

所以這個(gè)中文翻譯過(guò)來(lái)的詞,就造成了我們對(duì) Object 的一定誤解。因?yàn)閷?duì)象在英文中,我覺(jué)得更接近 target 這個(gè)單詞的意思。其實(shí)在臺(tái)灣就會(huì)把 Object 翻譯成 “物件”。物件這個(gè)詞在語(yǔ)義上確實(shí)會(huì)更貼合一些,但是物件這個(gè)詞大家也不是特別熟悉,所以它就演變成了一個(gè)技術(shù)的專用名詞。

但是不論如何,我們腦子里面應(yīng)該是有這么一個(gè)概念的,從小我們就應(yīng)該知道我們有三條一模一樣的魚(yú),但是其實(shí)他是三個(gè)不同的對(duì)象。那為什么一模一樣的魚(yú),他們是不同的對(duì)象呢?

我們可以這么理解哈,突然有一天其中一條魚(yú)的尾巴被咬掉了。很驚奇的發(fā)現(xiàn),另外兩條魚(yú)并不會(huì)受到影響。因此,當(dāng)我們?cè)谟?jì)算機(jī)中描述這三條魚(yú)的時(shí)候,那肯定是三組相同的數(shù)據(jù)的對(duì)象,但是是單獨(dú)儲(chǔ)存了三份,互相獨(dú)立的

這種魚(yú)和魚(yú)之間的區(qū)別其實(shí)就是,他們的對(duì)象的一個(gè)特性的體現(xiàn)。一些認(rèn)知學(xué)的研究認(rèn)為我們?nèi)嗽谛r(shí)候大概 5 歲的時(shí)候就有

這樣的認(rèn)知了,其實(shí)現(xiàn)在的孩子發(fā)育的比較早,5歲已經(jīng)是一個(gè)最低的年齡了。2 ~ 3 歲的時(shí)候大家都知道這個(gè)蘋(píng)果和那個(gè)蘋(píng)果是不一樣的,這個(gè)咬一口,另外一個(gè)蘋(píng)果安然無(wú)事。

所以如果我們?cè)谟?jì)算機(jī)里面描述這三條魚(yú)的時(shí)候,我們就必須要把數(shù)據(jù)單獨(dú)存儲(chǔ)三份,因?yàn)槭侨齻€(gè)對(duì)象的狀態(tài),而不是我們把同一個(gè)數(shù)據(jù)存了三份,而是恰巧他們是相等而已。其實(shí)這個(gè)正是所有的面向?qū)ο缶幊痰囊粋€(gè)基礎(chǔ),也就是說(shuō),他是這條魚(yú)就是這條魚(yú),不是這條魚(yú)就不是這條魚(yú),不會(huì)因?yàn)閷?duì)象本身的狀態(tài)改變而變得有區(qū)別。

所以我們對(duì)對(duì)象的認(rèn)知是?

任何一個(gè)對(duì)象都是唯一的,這與它本身的狀態(tài)無(wú)關(guān),狀態(tài)是由對(duì)象決定的

即使?fàn)顟B(tài)完全一致的兩個(gè)對(duì)象,也并不相等。所以有時(shí)候我們會(huì)把對(duì)象當(dāng)數(shù)據(jù)用,但是這個(gè)其實(shí)是一種語(yǔ)言的使用技巧而已,并不是把對(duì)象當(dāng)做對(duì)象用,比如我們傳一個(gè) config,其實(shí)傳 config 的過(guò)程其實(shí)它并不是把對(duì)象當(dāng)對(duì)象去傳,而是我們把對(duì)象當(dāng)成一種數(shù)據(jù)載體去傳。這個(gè)時(shí)候就涉及到我們對(duì)對(duì)象類型的使用,跟語(yǔ)言本身的設(shè)計(jì)用途的偏差。

我們用狀態(tài)來(lái)描述對(duì)象,比如我們有一個(gè)對(duì)象 “魚(yú)”,然后他的狀態(tài)就是,它有沒(méi)有 “尾巴”、“眼睛多大”,我們都會(huì)用這些狀態(tài)值來(lái)描述一個(gè)對(duì)象。

我們的狀態(tài)的改變既是行為,狀態(tài)的改變就是魚(yú)的尾巴沒(méi)有了,被咬掉了。然后過(guò)了一段時(shí)間它又長(zhǎng)出一條新尾巴了,然后尾巴還可以來(lái)回?cái)[動(dòng)。這些都屬于它的狀態(tài)的改變。而這些狀態(tài)的改變都是行為。

Object 三要素

JavaScript 對(duì)象是什么

  • Identifier —— 唯一標(biāo)識(shí)
  • State —— 狀態(tài)
  • Behavior —— 行為

其實(shí)哲學(xué)家他們就會(huì)研究一個(gè) Object,比如魚(yú)的唯一標(biāo)識(shí)是什么,這條魚(yú)的骨頭全部挑出來(lái)看還是不是這條魚(yú)。然后把肉都切下來(lái),再拼起來(lái)看是不是這一條魚(yú),這就是著名的哲學(xué)問(wèn)題 “忒修斯之船”。

這個(gè)我們就不用關(guān)心,我們就說(shuō)變量它是有一個(gè)唯一標(biāo)識(shí)性,這個(gè)也是對(duì)象的一個(gè)核心要素具備了。

對(duì)象就要有狀態(tài),狀態(tài)是可以被改變的,改變就是行為。這樣對(duì)象的三要素就成立了。

我們腦子里的任何一個(gè)概念和現(xiàn)實(shí)中的任何一個(gè)物品,都可以成為一個(gè)對(duì)象,只要三要素是齊備的。

Object —— Class(類)

首先 Class 類 和 Type 類型是兩個(gè)不一樣的概念。

我們認(rèn)識(shí)對(duì)象的一個(gè)重要的方式叫做分類,我們可以用分類的方式去描述對(duì)象。比如我們研究透測(cè)一條魚(yú)之后,它與所有同類型的魚(yú)特性都是類似的,所以我們就可以把這些魚(yú)歸為一類,叫 “魚(yú)類”(Fish Class)。

其實(shí)在魚(yú)的分類上還有更大的為 “動(dòng)物分類 (Animal)”,那么動(dòng)物下面還有其他動(dòng)物的分類,比如說(shuō)羊 (Sheep)。所以說(shuō)魚(yú)和羊之間他們的共性就會(huì)用 “動(dòng)物” 來(lái)描述。然后我們一層一層的抽象,在 "Animal" 之上還會(huì)有 Object。

類是一個(gè)非常常見(jiàn)的描述對(duì)象的一種方式,比如說(shuō)我們剛剛講到的生物,用對(duì)象可以把所有的生物分成界門綱目科屬種,是一個(gè)龐大的分類體系。在寫(xiě)代碼的時(shí)候,分類是一個(gè)為業(yè)務(wù)服務(wù)的,我們沒(méi)有必要分的那么細(xì)。通常我們會(huì)把有共性的需要寫(xiě)在代碼里的,我們就把 Animal 提出來(lái),就不再分這個(gè)哺乳動(dòng)物,還是卵生,還是脊索動(dòng)物等等。

分類有兩個(gè)流派,一種是歸類,一種是分類。

  • 歸類 —— 就是我們?nèi)パ芯繂蝹€(gè)對(duì)象,然后我們從里面提取共性變成類,之后我們又在類之間去提取共性,把它們變成更高的抽象類。比如我們?cè)?“羊” 和 “魚(yú)” 中提取共性,然后把它們之間的共享再提取出來(lái)變成 “動(dòng)物” 的類。對(duì)于 “歸類” 方法而言,多繼承是非常自然的事情,如 C++ 中的菱形繼承,三角形繼承等。
  • 分類 —— 則是把世界萬(wàn)物都抽象為一個(gè)基類 Object,然后定義這個(gè) Object 中有什么。采用分類思想的計(jì)算機(jī)語(yǔ)言,則是單繼承結(jié)構(gòu)。并且會(huì)有一個(gè)基類 Object。

JavaScript 這個(gè)語(yǔ)言比較接近 “分類” 這個(gè)思想,但是它也不完全是分類的思想,因?yàn)樗且粋€(gè)多范式的面向?qū)ο笳Z(yǔ)言。

Object —— Prototype(原型)

接下來(lái)我們講一講 JavaScript 描述對(duì)象的方式。

其實(shí)分類 Class Based 的 Object 并不是一個(gè)唯一的認(rèn)識(shí)對(duì)象的方法,我們還有一個(gè)更接近人類自然認(rèn)知的。分類的能力可能至少要到小學(xué)才有的。但是我們認(rèn)識(shí)對(duì)象之后,幾乎是馬上就可以得到另外一種描述對(duì)象的方式。那就是 “原型”。

原型其實(shí)用 “照貓畫(huà)虎” 來(lái)理解 ,其實(shí)照貓畫(huà)虎就是用的一種原型方法。因?yàn)樨埡突⒑芟?,所以我們只需要把它們直接的有區(qū)別的地方分出來(lái)就可以了。

比如說(shuō)我們現(xiàn)在想研究魚(yú),那么找一種典型的魚(yú),比如找一條具體的鯉魚(yú),然后我們把這條鯉魚(yú)所有的特征都加到魚(yú)類的原型上。其他的魚(yú)只要有對(duì)象,我們就根據(jù)魚(yú)的原型進(jìn)行修改。比如說(shuō)鯰魚(yú)比鯉魚(yú)更能吃,它是吃肉的,而且身上還是滑滑的,所以我們就可以在鯉魚(yú)的原型基礎(chǔ)上把這些特征加上,這樣我們就能描述出鯰魚(yú)了。

那么在羊類里面,我們也選中一只小綿羊來(lái)做我們的基礎(chǔ)原型。然后如果我們找到一只山羊,我們分析出它的特性是多胡子,腳是彎點(diǎn),又長(zhǎng)又硬又能爬山,那么我們就在小綿羊的原型上加上這些特性,那我們就描述了一只山羊了。

那么在上級(jí)的 “動(dòng)物” 中我們也選一只典型的動(dòng)物,比如說(shuō)老虎,有四個(gè)蹄,但是不一定所有動(dòng)物都有4個(gè)蹄子,不過(guò)原型選擇相對(duì)來(lái)說(shuō)它是比較自由的。比如說(shuō)我們選擇蛇作為動(dòng)物的原型的話,那么我們?cè)诿枋鲷~(yú)的時(shí)候就特別費(fèi)勁了,描述貓的時(shí)候就更費(fèi)勁了。

原型里面也會(huì)有一個(gè)最終版的原型叫 Object Prototype,這個(gè)就是所有物品的典型的物品,也可以說(shuō)是我們所有對(duì)象的老祖宗。我們描述任何對(duì)象都是從它與描述對(duì)象的區(qū)別來(lái)進(jìn)行描述的。

然后在 Object Prototype 之上一般來(lái)說(shuō)是不會(huì)再有原型了,但是有一些語(yǔ)言里面會(huì)允許有一種 Nihilo 原型。Nihilo 的意思就是虛無(wú)空虛,這個(gè)是語(yǔ)言中立的講法。如果我們用 JavaScript 的具體的設(shè)施來(lái)描述,那這個(gè) Nihilo 原型就是 null,這個(gè)大家就很容易理解了,我們很容易就可以簡(jiǎn)歷一個(gè) null 對(duì)象的原型。

小總結(jié):

  • 我們這種原型是更接近人類原始認(rèn)知的描述對(duì)象的方法
  • 所以面向?qū)ο蟮母鞣N方法其實(shí)并沒(méi)有絕對(duì)的對(duì)錯(cuò),只存在在不同場(chǎng)景下不同的代價(jià)
  • 原型的認(rèn)知成本低,選錯(cuò)的成本也比較低,所以原型適合一些不是那么清晰和描述上比較自由的場(chǎng)景
  • 而分類(Class)更適合用在一些比較嚴(yán)謹(jǐn)?shù)膱?chǎng)景,而 Class 有一個(gè)優(yōu)點(diǎn),它天然的跟類型系統(tǒng)有一定的整合的,所以很多的語(yǔ)言就會(huì)選擇把 Class 的繼承關(guān)系整合進(jìn)類型系統(tǒng)的繼承關(guān)系當(dāng)中

小練習(xí)

我們?nèi)绻枰帉?xiě)一個(gè) “狗 咬 人” 的 Class,我們需要怎么去設(shè)計(jì)呢?

如果我們按照一個(gè)比較樸素的方法,我們就會(huì)去定義一個(gè) Dog Class,然后里面給予這個(gè) Class 一個(gè) bite 的方法。

class Dog {
  bite(Human) {    // ......
  }
}復(fù)制代碼

這樣的一段代碼是跟我們的題目是一模一樣的,但是這個(gè)抽象是一個(gè)錯(cuò)誤的抽象。因?yàn)檫@個(gè)違背了面向?qū)ο蟮幕咎卣?,不管我們是怎么設(shè)計(jì),只要這個(gè) bite 發(fā)生在狗身上就是錯(cuò)誤的。

為什么?

因?yàn)槲覀兦懊嬷v到了面向?qū)ο蟮娜?,?duì)象的狀態(tài)必須是對(duì)象本身的行為才能改變的。那么如果我們?cè)诠返?Class 中寫(xiě) bite 這個(gè)動(dòng)作,但是改變的狀態(tài)是 “人”,最為狗咬了人之后,只會(huì)對(duì)人造成傷害。所以在這個(gè)行為中 “人” 的狀態(tài)是發(fā)生變化的,那么如果行為是在狗的 Class 中就違反了面向?qū)ο蟮奶卣髁恕?/p>

當(dāng)然如果是狗吃人,那我們勉強(qiáng)是可以成立的,因?yàn)楣烦粤巳斯肪惋柫?,那?duì)狗的狀態(tài)是有發(fā)生改變的。但是狗咬人,我們基本可以認(rèn)為這個(gè)行為對(duì)狗的狀態(tài)是沒(méi)有發(fā)生任何改變的。

所以我們應(yīng)該在 “人” 的 Class 中設(shè)計(jì)一個(gè)行為。那么有些同學(xué)就會(huì)問(wèn),我們是應(yīng)該在人的身上加入一個(gè) biteBy 行為嗎?就是人被咬的一個(gè)行為?似乎也不對(duì),因?yàn)槿?Class 里面的行為應(yīng)該是用于改變?nèi)说臓顟B(tài)的,那這個(gè)行為的命名應(yīng)該是怎么樣的呢?

這里更加合理的行為應(yīng)該是 hurt 表示被傷害了,然后傳入這個(gè)行為的參數(shù)就是受到的傷害程度 damage。因?yàn)檫@里人只關(guān)心它受到的傷害有多少就可以了,他是不需要關(guān)心是狗咬的還是什么咬的。

class Human {
  hurt(damage) {    //......
  }
}復(fù)制代碼

狗咬人在實(shí)際開(kāi)發(fā)場(chǎng)景中,是一個(gè)業(yè)務(wù)邏輯,我們只需要設(shè)計(jì)改變?nèi)?Human 對(duì)象內(nèi)部的狀態(tài)的行為,所以它正確的命名應(yīng)該是 hurt。這里的 damage,可以從狗 Class 中咬 bite, 的行為方法中計(jì)算或者生成出來(lái)的一個(gè)對(duì)象,但是如果我們直接傳狗 Dog 的對(duì)象進(jìn)來(lái)的話,肯定是不符合我們對(duì)對(duì)象的抽象原則的。

最終我們的代碼實(shí)現(xiàn)邏輯如下:

class Human {  constructor(name = '人') {    this.name = name;    this.hp = 100;
  }

  hurt(damage) {    this.hp -= damage;    console.log(`${this.name} 受到了 ${damage} 點(diǎn)傷害,剩余生命中為 ${this.hp}`);
  }
}class Dog {  constructor(name = '狗') {    this.name = name;    this.attackPower = 10; // 攻擊力
  }

  bite() {    return this.attackPower;
  }
}let human = new Human('三鉆');let dog = new Dog();

human.hurt(dog.bite()); // 輸出:三鉆 受到了 10 點(diǎn)傷害,剩余生命中為 90復(fù)制代碼

設(shè)計(jì)對(duì)象的原則

  • 我們不應(yīng)該受到語(yǔ)言描述的干擾(特別是業(yè)務(wù)需求的干擾)
  • 在設(shè)計(jì)對(duì)象的狀態(tài)和行為時(shí),我們總是遵循 “行為改變狀態(tài)” 的原則
  • 違背了這個(gè)原則,整個(gè)對(duì)象的內(nèi)聚性就沒(méi)有了,這個(gè)對(duì)架構(gòu)上會(huì)造成巨大的破壞

看完了這篇文章,相信你對(duì)JavaScript 對(duì)象是什么有了一定的了解,想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI