數(shù)組可以擁有字符串的方法,字符串擁有數(shù)組的方法,而 json 同時擁有以上兩種方法,是不是很神奇?其實我倒是喜歡管這種方法叫做「數(shù)據(jù)類型欺騙」。
創(chuàng)新互聯(lián)建站專注于企業(yè)全網(wǎng)營銷推廣、網(wǎng)站重做改版、康平網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5場景定制、商城開發(fā)、集團公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為康平等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。首先說一下 js 中兩個比較接近的數(shù)據(jù),一個叫數(shù)組,一個叫 json。為什么先拿這兩個講呢?第一點,它倆都是一個“ 爹 ”,沒錯,都是Obj。再說一下他倆不一樣的地方。
json沒有 length ,準確的說是 json 的 length 是 undefined 。其實這只是這個對象的一個私有屬性而已,因為沒有這條私有屬性,所以才是 undefined。而 Array.prototype 里面有 length 的方法,第二個數(shù)組可以用中括號取到對應(yīng)的值也就是:
var a = [1,2,3];
a[0]//1
a[1]//2
中括號里面必須放數(shù)字,而這個特性其實 json 算是支持的。這就是給了咱們一個可乘之機。
ok,現(xiàn)在就用 json 偽造一個 [1,2,3] 的對象。
var a = {
'0':1
'1':2,
'2':2
} ;
在json中鍵值對中的key值只說明了不能用Number作為key值,ok既然如此,我可以用字符串的0,1,2.
這樣如此做的話
a[0] //1
a[1] //2
似乎可以欺騙了系統(tǒng)了,當然還差最后一步也就是length,ok,我們直接賦予一個length。
var a = {
'0':1
'1':2,
'2':2,
length:3
} ;
這樣的一個 a 其實在輸出的時候和 [1,2,3] 就完全一樣了。說白了,我們已經(jīng)用一個 json,在不看內(nèi)容的前提下其實可以完全騙過人的眼睛了。
到底能不能騙過系統(tǒng)的眼睛呢?在試驗前我們先來講一下對象的方法實現(xiàn)原理。其實所有的實例化對象的方法的函數(shù) this 都是指向,你要操作的數(shù)據(jù)最后在 return 出 this。
咱們借助這個道理來試一試 用這個偽裝的 json 能不能用數(shù)組的方法。首先,咱們先試試slice。
a.slice()//報錯 沒有該方法
[].slice.call(a) // 1,2,3 成功的騙過了瀏覽器
我們在深入一點試試。
Array.prototype.slice.call(a,1)// 2,3 確實截取到了。
如果這個 json 對象沒有 length 的屬性的時候,則會返回一個空數(shù)組,說明數(shù)組的 length 在這個方法中是會用到的。而咱們的 json,有了和數(shù)組一樣的所有東西后,在變成這個方法的 this 之后,其實也可以騙過瀏覽器來執(zhí)行數(shù)組的方法。
當然咱們再來一個比較稍微高難度的例子吧,數(shù)組有一堆屬于自己的循環(huán),例如:find 、 forEach 、findIndex咱們就試驗最后一個吧。
[].findIndex.call(a,(function(e,index){
console.log(e);1,2,3
console.log(index); 0,1,2
}));
一點問題都沒有,其實實測之后發(fā)現(xiàn),數(shù)組的大部分方法都可以使用,這也就是說明了 json 完全也可以使用數(shù)組的方法,不過 json 要使用的話,還需要 key 值和 length 符合象數(shù)組一樣,不過似乎也沒啥意義了。當然 json 可不可以用字符串的方法呢?
var a = '123';
和
var a = {
'0':'1'
'1':'2',
'2':'2',
length:3
} ;
似乎在輸出的時候沒有什么明顯的差異,他們的 a[0] 都是1,length也都是3。ok,讓我們試試
'.substring.call(a)//'[object object]'
可以使用沒有報錯,也就是說 substring 認這個東西了。但是,內(nèi)部他到內(nèi)部就暴露了真實的自己他是一個對象,解析出來的 this 就是 obj 。最后也會 return 出這個東西來。當然你會說,字符串也有 new String 如果把這個放進去 會出現(xiàn)問題么?來,帶著疑問我們來看看。
var a = new String('123');
''.substring.call(a) //'123';
而我試驗了幾個方法之后發(fā)現(xiàn)雖然沒報錯,但是,輸出都是字符串'[object object]'。人家字符串自己的對象卻是一點都沒事,這其實也深度反應(yīng)了一個問題。字符串的對象雖然具有對象的引用,或者說是私有屬性所有特性,但是和 array 和 obj 的對象還是有一些本質(zhì)的差別。當然玩完了 json,咱們來試試 數(shù)組玩字符串的。
var a = [1,2,3];
''.substring.call(a,1)//,2,3;
沒報錯,而且數(shù)組也刷了一回字符串的 substring 方法,超級酷。但是截取值確有些不是我們想要的。是',2,3';
其實不難發(fā)現(xiàn) 是到了內(nèi)部數(shù)組變成了 '1,2,3',從第一個開始截取 自然最后就出現(xiàn)了',2,3';
其實試驗了幾種方法之后,發(fā)現(xiàn)字符串對數(shù)組還是蠻友好的,大部分都是支持的,但是你的數(shù)組放進去之后,會自動轉(zhuǎn)換成字符串帶逗號的。就像[1,2,3]轉(zhuǎn)化成'1,2,3';不過數(shù)組方法對字符串其實就沒那么友好了,不過有些方法還是蠻好使的。例如:
[].slice.call('123',1)//['2','3'];
變成了一個數(shù)組的 ['2','3'] 也就是‘123’在進去后自動變成了 一個['1','2','3']在從第一位開始截取的話 就變成['2','3']了,似乎效果不錯 因為省下了 split('') 步驟,不過它也是只能一個字母一個字母變成分割,變成數(shù)組。不過一些別的方法就沒著么走運了,例如:
var a = '123';
[].push.call(a,'4')//報錯
其實試驗了大部分,發(fā)現(xiàn)可以用的確實不多,不過還是有一小部分可以使用。
總之,這個東西其實在實戰(zhàn)中沒有什么實際的意義,不過如果要說的話就是其實數(shù)組、字符串、json的方法部分是可以通用的。
歡迎點擊進入李游Leo老師的前端課堂
點擊進入本站最全全棧課程《李游Leo - Web前端,從零基礎(chǔ)到全棧工程師》帶你用最快的時間一步月薪上萬
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。