解開那一層面紗瘾晃,js類數(shù)組的小秘密(下篇)

前言:

解開那一層面紗蹦误,js類數(shù)組的小秘密(上篇)里面,已經(jīng)提到類數(shù)組的定義尚镰,以及常見的類數(shù)組類型哪廓,類數(shù)組的轉(zhuǎn)化涡真,接下來我們來探討如何定義一個(gè)類數(shù)組對象?類數(shù)組是否可以借用數(shù)組上面的方法缸剪?jQuery類數(shù)組對象的表現(xiàn)杏节?

1.如何定義一個(gè)類數(shù)組對象典阵?

根據(jù)上面文章的定義:

  • 擁有l(wèi)ength屬性壮啊,其它屬性(索引)為非負(fù)整數(shù)
  • 不具有數(shù)組所具有的方法(非必須)
    如果想自己創(chuàng)一個(gè)類數(shù)組對象是很容易的:
let arrLike = {
    0: "a",
    1: "b",
    2: "c",
    length: 3
};

然后我們使用魯大師(lodash.js v4.17.5)來判斷下,我們創(chuàng)建的是不是滿足條件:

import { isArrayLike, isArrayLikeObject } from "lodash/index";
isArrayLike(arrLike ); // true
isArrayLikeObject(arrLike ); // true

親測是滿足條件的玄渗,那接下來我們就去操作類數(shù)組藤树。

2.“借用”數(shù)組方法來操作類數(shù)組對象

之前已經(jīng)實(shí)現(xiàn)類數(shù)組轉(zhuǎn)成數(shù)組,是借用數(shù)組上面的slicesplice方法巡莹,那么在不把類數(shù)組轉(zhuǎn)成數(shù)組的情況下降宅,我們也是可以像操作數(shù)組一樣操作類數(shù)組對象:

let arrLike = {0: "a", 1: "b", 2: "c", length: 3};

Array.prototype.push.call(arrLike, "d"); // 4, arrLike = {0: "a", 1: "b", 2: "c", 3: "d", length: 4}
Array.prototype.pop.call(arrLike); // 3, arrLike = {0: "a", 1: "b", 2: "c", length: 3}
Array.prototype.slice.call(arrLike, 1); // ["b", "c"], arrLike = {0: "a", 1: "b", 2: "c", length: 3}
Array.prototype.splice.call(arrLike, 1, 1); // ["b"], arrLike = {0: "a", 1: "c", length: 2}
....... // other methods eg. map, forEach, filter...

上面測試了“一些方法”(并不是全部)腰根,都是可以實(shí)現(xiàn)我們想要的效果拓型。既然并不是全部方法都能借用以后得到期望的效果劣挫,那么是誰這么特殊呢?

3. 特殊的Array.prototype.concat

上面演示了類數(shù)組對象借用數(shù)組的方法球拦,來實(shí)現(xiàn)一些操作帐我,但是是不是數(shù)組的所有方法拦键,被借用以后都能達(dá)到和操作數(shù)組一樣的效果呢芬为?
我們來看一段代碼:

let arrLike = {0: "a", 1: "b", 2: "c", length: 3};
let arr = ["a", "b", "c"];

arr.concat("d", "e", "f"); // ["a", "b", "c", "d", "e", "f"]

我們期待[].concat.call(arrLike, "d", "e", "f");運(yùn)行的結(jié)果是{ 0: "a", 1: "b", 2: "c", 3: "d", 4: "e", 5: "f", length: 6 }然而結(jié)果卻是:

[].concat.call

在看一個(gè)例子:
image.png

原因是concat內(nèi)部會新創(chuàng)建一個(gè)數(shù)組媚朦,來接收傳入的每一項(xiàng)莲镣,如果傳入的是數(shù)組涎拉,會先對數(shù)組進(jìn)行一次展平,然后把所有項(xiàng)都放入這個(gè)新數(shù)組半火,結(jié)果就是我們看到的結(jié)果了钮糖,并沒根據(jù)length進(jìn)行操作,所以沒有看到我們期望的效果阎抒。
還好我們可以使用push來實(shí)現(xiàn)我們想要的效果

let arrLike = {0: "a", 1: "b", 2: "c", length: 3};
Array.prototype.push.call(arrLike, "d", "e", "f"); // 6, arrLike = {0: "a", 1: "b", 2: "c", 3: "d", 4: "e", 5: "f", length: 6}

4.jQuery類數(shù)組對象的表現(xiàn)

既然上面我們已經(jīng)對類數(shù)組對象有了一些認(rèn)識且叁,那jQuery獲取到的結(jié)果也是類數(shù)組對象逞带,看下圖:

jQuery類數(shù)組對象

再看看我們自己創(chuàng)建的類數(shù)組對象:
普通的類數(shù)組對象

對比下可以看出很明顯的區(qū)別展氓,我們創(chuàng)建的好像就是對象脸爱,而jQuery得到的結(jié)果卻是“長得像”數(shù)組阅羹,這是為什么呢勺疼,
再看jQuery.fn上面打印出來的結(jié)果,我們可以發(fā)現(xiàn)一些數(shù)組上面的方法:下圖是jQuery原型上的部分截圖
jQuery原型方法部分截圖

很面熟捏鱼,好像是數(shù)組的方法我們來驗(yàn)證下:

jQuery.fn.sort === [].sort; // true
jQuery.fn.splice === [].splice; // true
jQuery.fn.slice === [].slice; // false
jQuery.fn.push === [].push; // true

其中有部分方法確實(shí)是來自數(shù)組执庐,但其實(shí)這幾個(gè)方法里面哪一個(gè)才是讓jQuery類數(shù)組對象和我們自己創(chuàng)建的類數(shù)組對象變相不一樣的原因呢?
進(jìn)過測試:

let arrLike = {0: "a", 1: "b", 2: "c", length: 3, splice: [].splice};
arrLike; // Object(3) ["a", "b", "c", splice: ?]

let arrLike01 = {0: "a", 1: "b", 2: "c", length: 3, sort: [].sort};
arrLike01; // {0: "a", 1: "b", 2: "c", length: 3, sort: ?}

原來是splice方法导梆,那么是不是必須是Array.prototype.splice呢轨淌?帶著這個(gè)疑問再次驗(yàn)證:

let arrLike = {0: "a", 1: "b", 2: "c", length: 3, splice: () => {} };
arrLike; // Object(3) ["a", "b", "c", splice: ?]

let arrLike = { 0: "a", 1: "b", 2: "c", length: 3, splice: [].sort };
arrLike; // Object(3) ["a", "b", "c", splice: ?]

let arrLike = { length: 0, splice: () => {} };
arrLike; // Object [splice: ?]

let arrLike = { length: 0, splice: 1 };
arrLike; // {length: 0, splice: 1}

let arrLike = { splice: () => {} };
arrLike; // {splice: ?}

從上面的結(jié)果可以明顯低看出,要想實(shí)現(xiàn)像jQuery一樣的類數(shù)組對象結(jié)構(gòu)看尼,只需要兩個(gè)條件:

  • 對象有一個(gè)length屬性递鹉,值為正整數(shù)
  • 含有一個(gè)splice方法
    其實(shí)jQuery內(nèi)部也是這樣做的藏斩,同樣含有splice方法躏结,只是jQuery原型上面的splcie方法,是數(shù)組上面的同名方法狰域。
jQuery.prototype.splice === Array.prototype.splice; // true

到這里關(guān)于“js類數(shù)組(對象)”的介紹就結(jié)束了媳拴,不得不感嘆js是一門神奇的語言黄橘,各種神秘的東西,繼續(xù)挖掘...

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末屈溉,一起剝皮案震驚了整個(gè)濱河市塞关,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌子巾,老刑警劉巖帆赢,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異线梗,居然都是意外死亡椰于,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門缠导,熙熙樓的掌柜王于貴愁眉苦臉地迎上來廉羔,“玉大人,你說我怎么就攤上這事僻造”锼” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵髓削,是天一觀的道長竹挡。 經(jīng)常有香客問我,道長立膛,這世上最難降的妖魔是什么揪罕? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮宝泵,結(jié)果婚禮上好啰,老公的妹妹穿的比我還像新娘。我一直安慰自己儿奶,他們只是感情好框往,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著闯捎,像睡著了一般椰弊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瓤鼻,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天秉版,我揣著相機(jī)與錄音,去河邊找鬼茬祷。 笑死清焕,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播秸妥,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼借卧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了筛峭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤陪每,失蹤者是張志新(化名)和其女友劉穎影晓,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體檩禾,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡挂签,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盼产。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饵婆。...
    茶點(diǎn)故事閱讀 40,852評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖戏售,靈堂內(nèi)的尸體忽然破棺而出侨核,到底是詐尸還是另有隱情,我是刑警寧澤灌灾,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布搓译,位于F島的核電站,受9級特大地震影響锋喜,放射性物質(zhì)發(fā)生泄漏些己。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一嘿般、第九天 我趴在偏房一處隱蔽的房頂上張望段标。 院中可真熱鬧,春花似錦炉奴、人聲如沸逼庞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽往堡。三九已至,卻和暖如春共耍,著一層夾襖步出監(jiān)牢的瞬間虑灰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工痹兜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留穆咐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像对湃,于是被迫代替她去往敵國和親崖叫。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評論 2 361

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

  • 前言: 在開發(fā)或者面試中,我們經(jīng)常會遇到或者被問到關(guān)于“類數(shù)組”的問題拆讯,什么是類數(shù)組脂男?什么是類數(shù)組對象?js里面哪...
    洛夕楓閱讀 437評論 0 1
  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,238評論 0 4
  • 第3章 基本概念 3.1 語法 3.2 關(guān)鍵字和保留字 3.3 變量 3.4 數(shù)據(jù)類型 5種簡單數(shù)據(jù)類型:Unde...
    RickCole閱讀 5,132評論 0 21
  • 上午十點(diǎn)多快十一點(diǎn)种呐,我正帶小寶在游樂場玩宰翅,老公打電話過來。游樂場很吵爽室,我聽不清楚他在說什么汁讼,想著沒什么大事就說你發(fā)...
    蕾蕾1702閱讀 242評論 1 1
  • 活著像一個(gè)植物 活著像一個(gè)動物 活著像一個(gè)人.
    tobesaiyi閱讀 95評論 0 0