JS在對(duì)象中使用數(shù)組方法

對(duì)對(duì)象的理解和探索第喳,可以從console.log()console.dir()看得很詳細(xì)满钟,一個(gè)簡(jiǎn)單示例

var a = [1,2,3] 
var b = {x:1,y:2,z:3}
var c = new String(123)
console.log(a,b,c)
三個(gè)原型表明了各自的類型

繼續(xù)跟循prototype指向咙崎,會(huì)發(fā)現(xiàn)所有類型的原型都是一個(gè)對(duì)象仗处,萬物皆對(duì)象……

來看一個(gè)例子:首先定義一個(gè)對(duì)象眯勾,給對(duì)象添加數(shù)組的pushsplice方法,然后執(zhí)行一下push方法婆誓。

var obj={
  '2':3,
  '3':4,
  'length':2,
  'splice':Array.prototype.splice,
  'push':Array.prototype.push
}
obj.push(1)
obj.push(2)
console.log(obj)

這似乎是不科學(xué)的吃环,對(duì)象怎么能使用數(shù)組的方法呢?我們先來看一下執(zhí)行結(jié)果

emmm……并沒有報(bào)錯(cuò)

2洋幻、3的值和length全部改變郁轻,證明塞進(jìn)去的方法起效了。
我們先看一下Array?.prototype?.push()文留,push()方法將一個(gè)或多個(gè)元素添加到數(shù)組的末尾好唯,并返回該數(shù)組的新長(zhǎng)度。由此可見該方法是有length返回值的燥翅,似乎都對(duì)應(yīng)上了骑篙,那么到底是怎么實(shí)現(xiàn)的呢?

//push的內(nèi)部原理
Arrary.prototype.push = function(target){
  this[this.length] = target    //把目標(biāo)值設(shè)為this數(shù)組的最后一項(xiàng)
  this.length ++    //設(shè)置數(shù)組的長(zhǎng)度权旷,使其+1
}
//----------------------
var a =[1,2,3]
console.log(a.length)    //---> 3
console.log(a[a.length-1])    //--->3

//我們套入剛才的對(duì)象進(jìn)行比對(duì)
var obj={
  '2':3,
  '3':4,
  'length':2,
  'splice':Array.prototype.splice,
  'push':Array.prototype.push
}

obj.push(1)
//-------------------------------
obj.push(1) = 1 => {
  obj[obj.length] = 1    //obj[2] = 1
  obj.length ++          //obj.length = 3
}
//-------------------------------

obj.push(2)
//-------------------------------
obj.push(2) = 2 => {
  obj[obj.length] = 2    //obj[3] = 2
  obj.length ++          //obj.length = 4
}
//-------------------------------

console.log(obj)
/*所以obj里的值就出來了
obj = {
  2: 1
  3: 2
  length: 4
}
吃透了原理替蛉,原來JS像加減法一樣簡(jiǎn)單*/

JS的世界如此奇妙,食髓知味拄氯,那么我們?cè)賮硌芯恳幌?code>splice()的原理吧躲查。
Array?.prototype?.splice()splice()方法通過刪除或替換現(xiàn)有元素或者原地添加新的元素來修改數(shù)組译柏,并以數(shù)組形式返回被修改的內(nèi)容镣煮。此方法會(huì)改變?cè)瓟?shù)組。
簡(jiǎn)而言之鄙麦,array.splice(start,deleteCount,value,...)方法實(shí)現(xiàn)了三個(gè)功能:插入典唇,刪除和替換,而且刪除了元素之后還會(huì)返回一個(gè)包含刪除元素的新數(shù)組

var a = [1,2,3,4]
console.log(a.splice(1,2),a)    
//[2,3],[1,4]  在索引值為1的位置刪除了兩個(gè)元素(刪除)

console.log(a.splice(1,0,2,3),a)    
//[],[1,2,3,4]  在索引值為1的位置刪除了0個(gè)元素并添加了兩個(gè)元素(插入)

console.log(a.splice(1,2,5,6),a)    
//[2,3],[1,5,6,4]  在索引值為1的位置刪除了兩個(gè)元素并添加了兩個(gè)元素(替換)

我們分析另外幾種情況:array.splice(s,d,v,...)

  • 刪除 (s,d)s為-1胯府,代表從倒數(shù)第1個(gè)開始介衔;②d不傳參,代表從s處刪到尾巴骂因;③d為負(fù)數(shù)炎咖,需要傳遞v,0或負(fù)數(shù)代表插入元素。
  • 插入 (s,0,v,...)s處插入v.length個(gè)元素乘盼,后段元素后移升熊。
  • 替換 (s,d,v,...)s處刪除d個(gè)元素,插入v.length個(gè)元素绸栅,視dv.length大小操作后段元素前移或后移级野。
    splice()方法一直詬病較多,從幾種方法的實(shí)現(xiàn)不難看出粹胯, start及之后的元素被全部重新排列了蓖柔,很是浪費(fèi)時(shí)間,我們先嘗試這幾種操作的代碼實(shí)現(xiàn)

Array?.prototype?.splice(start,deleteCount,value) = function(s,d,v){
for(var i = 0,i<d,i++){ this[s] } 新建數(shù)組风纠,根據(jù)s d傳入刪除元素渊抽,等待返回;調(diào)用內(nèi)部方法刪除指定位置數(shù)組元素议忽;準(zhǔn)備value列表,在s處插入十减,其后元素依次向后平移栈幸;考慮d>v.length時(shí),原數(shù)組后段元素向前平移……}阿西吧帮辟,好吧速址,我說著玩的,嘗試失敗【手動(dòng)捂臉】

回到前面的例子由驹,推導(dǎo)不出來詳細(xì)的實(shí)現(xiàn)代碼怎么計(jì)算所得值呢芍锚?上邊測(cè)試結(jié)果用的是火狐開發(fā)者工具,現(xiàn)在轉(zhuǎn)用chrome蔓榄,截張圖看看

var obj={
  '2':3,
  '3':4,
  'length':4,
  'splice':Array.prototype.splice,
  'push':Array.prototype.push
}
console.log(obj)

Object(4) [empty × 2, 3, 4, splice: ?, push: ?]看到這里就好玩了并炮,chrome把符合數(shù)組結(jié)構(gòu)的對(duì)象(有數(shù)組的屬性)注釋為數(shù)組了,而對(duì)應(yīng)的鍵變成了索引般的存在甥郑。這里把length變成了4逃魄,是為了對(duì)應(yīng)“索引”3(3:4),這樣再按數(shù)組計(jì)算就可以了澜搅。
obj.splice(2,1)操作[empty,empty,3,4]數(shù)組伍俘,應(yīng)該得到[empty,empty,4],再回到原對(duì)象結(jié)構(gòu)勉躺,就是{2:4,length:3}我們截個(gè)圖see see


我們來走個(gè)測(cè)試癌瘾,驗(yàn)證一下

var obj={
  '2':3,
  '3':4,
  'length':4,
  'splice':Array.prototype.splice,
  'push':Array.prototype.push
}    //[empty,empty,3,4]
obj.splice(2,0,5,6)    //[empty,empty,5,6,3,4]
obj.splice(0,4,1,2)    //[1,2,3,4]
console.log(obj)

成了,就是這么計(jì)算的

當(dāng)對(duì)象擁有數(shù)組的“l(fā)ength”和“索引”時(shí)饵溅,可以認(rèn)為是個(gè)偽數(shù)組[ArrayLike]妨退,我們這個(gè)等于強(qiáng)塞進(jìn)去兩個(gè)數(shù)組的方法,需要注意的是,push()splice()還不太一樣碧注,push()是特意設(shè)計(jì)為通用的嚣伐,splice()對(duì)對(duì)象用起來還有局限,start超過length的值就操作不動(dòng)了萍丐。再看一眼官方push()的例子

var obj = {
    length: 0,
    addElem: function addElem (elem) {
        [].push.call(this, elem);
    }
};
//加兩個(gè)空對(duì)象
obj.addElem({});
obj.addElem({});
console.log(obj.length,obj);    
// → 2      {0: {}, 1: {}, length: 2, addElem: ?}

異曲同工轩端,不過人家的更為規(guī)整。本篇先記錄到這逝变,發(fā)現(xiàn)好玩的例子再來添加基茵。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市壳影,隨后出現(xiàn)的幾起案子拱层,更是在濱河造成了極大的恐慌,老刑警劉巖宴咧,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件根灯,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡掺栅,警方通過查閱死者的電腦和手機(jī)烙肺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來氧卧,“玉大人桃笙,你說我怎么就攤上這事∩尘” “怎么了搏明?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)闪檬。 經(jīng)常有香客問我星著,道長(zhǎng),這世上最難降的妖魔是什么粗悯? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任强饮,我火速辦了婚禮,結(jié)果婚禮上为黎,老公的妹妹穿的比我還像新娘邮丰。我一直安慰自己,他們只是感情好铭乾,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布剪廉。 她就那樣靜靜地躺著,像睡著了一般炕檩。 火紅的嫁衣襯著肌膚如雪斗蒋。 梳的紋絲不亂的頭發(fā)上捌斧,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音泉沾,去河邊找鬼捞蚂。 笑死,一個(gè)胖子當(dāng)著我的面吹牛跷究,可吹牛的內(nèi)容都是我干的姓迅。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼俊马,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼丁存!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起柴我,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤解寝,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后艘儒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體聋伦,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年界睁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嘉抓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡晕窑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出卵佛,到底是詐尸還是另有隱情杨赤,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布截汪,位于F島的核電站疾牲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏衙解。R本人自食惡果不足惜阳柔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蚓峦。 院中可真熱鬧舌剂,春花似錦、人聲如沸暑椰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽一汽。三九已至避消,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背岩喷。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工恕沫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留第步,地道東北人所计。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像报强,于是被迫代替她去往敵國(guó)和親妇穴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子爬虱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351