JavaScript中的 [].slice.call(args)

跟你不知道的js同款黃

神秘的語(yǔ)法

一直覺(jué)得 JS 是門神奇的語(yǔ)言,使用者不需要完全知曉底層概念,簡(jiǎn)單項(xiàng)目者甚至不需要會(huì)用這門語(yǔ)言就能使用它完成大大小小的項(xiàng)目。語(yǔ)言作者們將其設(shè)計(jì)的太好用,很多的開發(fā)者對(duì)于一些基礎(chǔ)概念都不求甚解。其中有一個(gè)很經(jīng)典的問(wèn)題是涉及到 .call() 這個(gè)方法在算法題中的應(yīng)用。

如果你也是將 JS 作為主力語(yǔ)言的前端攻城獅們,不知道你們有沒(méi)遇到過(guò)想實(shí)現(xiàn)某種功能卻無(wú)從下手的感覺(jué),最近在學(xué)習(xí)《你不知道的JavaScript》這本書的時(shí)候,果不其然遇到了我既熟悉又陌生的 [].slice.call(args) 語(yǔ)法的應(yīng)用。

想要往更深處行走,這些以前覺(jué)得晦澀的語(yǔ)法看起來(lái)也是避不開了。

不熟不吃

很多老師都會(huì)這么教,無(wú)論學(xué)習(xí)什么,都要先找到自己熟悉的部分下手。

乍一看,這個(gè)東西其實(shí)我是認(rèn)識(shí)的鴨,分解開來(lái)除了 call 以外都是很經(jīng)常用到的東西(.call其實(shí)也很常用,一般將 call 方法用于強(qiáng)制指定 this 的指向)

[ ]

乍一想,中括號(hào)??

貌似在 JS 里我們見(jiàn)到的 [] 更多是作為數(shù)組的形式出現(xiàn)的

馬克思爺爺說(shuō)過(guò)實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn)

那么我們就來(lái)看看它們之間的關(guān)系吧!

Object.getOwnPropertyNames( [] )
//["length"]

Object.getOwnPropertyNames( Array.prototype )
//(37) ["length", "constructor", "concat", "pop", "push", "shift", "unshift", "slice", "splice", "includes", "indexOf", 
//"keys", "entries", "forEach", "filter", "map", "every", "some", "reduce", "reduceRight", "toString", 
//"toLocaleString", "join", "reverse", "sort", "lastIndexOf", "copyWithin", "find", "findIndex", "fill", "remove", 
//"removeFirstIf", "removeIf", "repeat", "last", "lastDef", "clone"]

Object.prototype.toString.call( [] )
//查看[]的類型
//若直接typeOf結(jié)果為object,因?yàn)锳rray也是Object
//"[object Array]"

[] instanceof Array
//true

從上面測(cè)試的結(jié)果可以看出 [] 果然就是數(shù)組本數(shù)了,其本身的屬性只有 length,但是其可以通過(guò)數(shù)組原型繼承到所有數(shù)組應(yīng)該有的方法。

.slice

從上一個(gè) [] 的測(cè)試?yán)镂覀兛梢郧逦吹?slice 方法存在于數(shù)組的原型鏈中,所以我們可以推測(cè)此 slice 就是彼 slice 了。

[].slice === Array.prototype.slice
//true

答案跟我們預(yù)想的完全一樣,但是 [] 本身并沒(méi)有 slice 這個(gè)方法,所以其是通過(guò)原型鏈查找得到的這個(gè)方法。

可能有的同學(xué)也不怎么經(jīng)常用 slice 這里搬運(yùn)一下文檔:

文檔.jpg

傳送門 >>>>JavaScript中的數(shù)組slice方法

.call

有關(guān) call 的用法可參照另一篇文章>>>>this用法

call 方法的作用其實(shí)就是主動(dòng)綁定 this 的指向。

[].slice.call(args)的使用

看到這里可能有人會(huì)問(wèn),不是還沒(méi)介紹 args 嗎?

這里的 args 只是一個(gè)占位符,并不是一個(gè)有意義的標(biāo)記項(xiàng)。寫成 args 是因?yàn)檫@種用法常用于將函數(shù)接收的參數(shù)分割存到數(shù)組里,占位符由此得名。

好了,結(jié)合上面我們的分解所得,串起來(lái)看一下這一個(gè)魔法是怎么工作的吧!

args 的 this 會(huì)被強(qiáng)制綁定至 [] 也即數(shù)組的原型鏈上,由此可以使用數(shù)組中含有的 slice 方法。

但是通常傳入的 args 應(yīng)該是預(yù)想中的數(shù)據(jù)類型,以保證函數(shù)的順利運(yùn)行,否則會(huì)發(fā)生很多難以定位的錯(cuò)誤。

下面我們來(lái)實(shí)驗(yàn)一下吧!

//一個(gè)經(jīng)典的使用場(chǎng)景是獲取函數(shù)中的auguments對(duì)象
function test(){
  var args = [].slice.call( arguments )
  console.log( args );
}

test( 'hello', '111' );
// ["hello", "111"]

總結(jié)

溫故而知新,??闯P?。

很多深入語(yǔ)言內(nèi)部機(jī)制的用法可能我們極少用到,但是一旦遇到可能會(huì)卡掉我們大量寶貴的工作時(shí)間。

更有甚者很多開發(fā)者對(duì)于自己不熟悉的領(lǐng)域敬而遠(yuǎn)之,現(xiàn)在的JS有點(diǎn)像我們開電燈時(shí)的操作,只知道按下開關(guān)會(huì)亮起一盞明亮的燈,而從未深入燈內(nèi)部進(jìn)行探究。


Clancy Lin
2019.2.8
I can be whatever I want to be

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容