如下,我們可以這么定義一個(gè)JavaScript函數(shù):
js
體驗(yàn)AI代碼助手
代碼解讀
復(fù)制代碼function ttt(string) {
alert(string)
}
執(zhí)行這個(gè)函數(shù),就可以像下面這樣編寫:
js
體驗(yàn)AI代碼助手
代碼解讀
復(fù)制代碼ttt('JavaScript是第二好的語言!CSS是第一!')
好了,簡(jiǎn)單介紹完畢??隙ㄓ泻芏嗉夹g(shù)超群的前端佬,還知道另外幾種函數(shù)調(diào)用方式,這里就不補(bǔ)充了。掘金社區(qū)有很多很多這樣的文章。
今天呢,主要給各位前端佬介紹幾種“平平無奇”的函數(shù)調(diào)用方式!而且不帶上面的小括號(hào)()。
而且這些調(diào)用方式并不是屬于個(gè)別瀏覽器的hack,而是在絕大部分瀏覽器上可以順利執(zhí)行。尤其最后一種方式,堪稱函數(shù)調(diào)用的天花板之一?。。?/p>
聲明!本知識(shí)大部分來自web安全大大佬Gareth Heyes博客學(xué)習(xí)!諸位需要精進(jìn)自己技藝的前端佬,可以搜搜看看!
以下所有調(diào)用,默認(rèn)都已經(jīng)定義了ttt函數(shù)。
好,Show Time:
1、``符號(hào)調(diào)用
上面這個(gè)符號(hào)看著像單引號(hào),其實(shí)不是,符號(hào)就是我們平常用的字符模版那個(gè)符號(hào)。然后如下敲出代碼:
js
體驗(yàn)AI代碼助手
代碼解讀
復(fù)制代碼ttt`JavaScript是世界上第二好的語言!CSS是第一!`
然后,刷新頁面執(zhí)行。
不出意外,網(wǎng)頁順利出現(xiàn)如下效果:
驚不驚喜?如果不驚喜,第二種開始。
2、throw + onerror方法調(diào)用
前端佬都知道,throw
語句用于拋出用戶自定義的異常,通常是這么用的:
js
體驗(yàn)AI代碼助手
代碼解讀
復(fù)制代碼throw new Error('JavaScript不是世界上第二好的語言!');
這樣會(huì)在瀏覽器中的控制臺(tái)中輸出這樣效果。
而onerror
比較獨(dú)特。一般是使用在html標(biāo)簽中,如果加載外部文件發(fā)生錯(cuò)誤時(shí),會(huì)被觸發(fā)。比如下面這種經(jīng)典用法。
js
體驗(yàn)AI代碼助手
代碼解讀
復(fù)制代碼<img src="image.gif" onerror="myFunction()">
直接在js語句直接寫這個(gè),也不會(huì)有報(bào)未定義之類的。
這兩種呢,都有調(diào)用某一函數(shù)的能力。然后兩個(gè)結(jié)合起來,就會(huì)發(fā)生奇妙的調(diào)用函數(shù)方式:
js
體驗(yàn)AI代碼助手
代碼解讀
復(fù)制代碼throw onerror=ttt,'JavaScript是世界上第二好的語言!CSS是第一!'
我也嘗試換了幾種事件,比如onload
、oncancel
、onabort
等,都不行,還是onerror
好使??!
怎么,還不夠行?再來第三種!
3、Function 調(diào)用
在 JavaScript 中,每個(gè)函數(shù)實(shí)際上都是一個(gè) Function 對(duì)象。用Function ,是可以直接用字符串,構(gòu)造一個(gè)函數(shù)的。
比如想要執(zhí)行上面定義的ttt函數(shù),就可以這么去調(diào)用:
js
體驗(yàn)AI代碼助手
代碼解讀
復(fù)制代碼Function('ttt("JavaScript是世界上第二好的語言!CSS是第一!")')()
但這個(gè)不是重點(diǎn),我們需要平平無奇的去掉小括號(hào)(),結(jié)合第一種方式,可以有如下操作:
js
體驗(yàn)AI代碼助手
代碼解讀
復(fù)制代碼Function`a${'ttt\x28`JavaScript是世界上第二好的語言!CSS是第一!`\x29'}a```
嘎嘎!
怎么,還不行?來第四種!
4、instanceof 調(diào)用
instanceof
、Symbol
、eval
用處,被面試過的前端佬都知道是什么意思。但如果按照下面這么去組合:
js
體驗(yàn)AI代碼助手
代碼解讀
復(fù)制代碼'ttt\x28"JavaScript是世界上第二好的語言!CSS是第一!"\x29'instanceof{[Symbol['hasInstance']]:eval}
不出意外,那就那么意外的執(zhí)行了ttt
函數(shù)。
為啥?這里先不介紹了,我們接下去介紹第五種!
5、valueOf 調(diào)用
valueOf可能很多前端佬不大用。在Object、Symbol、Boolean、Date、String、Number
等對(duì)象中都有這個(gè)方法,主要作用,是將自身指向返回。
功能調(diào)用不多說,在社區(qū)很多文章介紹。但如下這種組合:
js
體驗(yàn)AI代碼助手
代碼解讀
復(fù)制代碼valueOf=ttt'JavaScript是世界上第二好的語言!CSS是第一!';window+''
也會(huì)一樣被執(zhí)行。
上面那種奇怪的組合,假如刪掉分號(hào);,或者window,或者+號(hào)都會(huì)語法報(bào)錯(cuò),唯獨(dú)那么組合起來,一點(diǎn)沒錯(cuò),函數(shù)還能被執(zhí)行。真正的神奇!
去執(zhí)行上面那樣帶有參數(shù)的函數(shù),簡(jiǎn)直有點(diǎn)可惜,丟失了簡(jiǎn)潔性。如果直接一個(gè)函數(shù)不需要參數(shù),那么也可以這么去調(diào)用:
js
體驗(yàn)AI代碼助手
代碼解讀
復(fù)制代碼valueOf=ttt;window+''
還不滿意?那么繼續(xù)上第六種??!
6、DOMMatrix 調(diào)用
先不說,直接上代碼:
js
體驗(yàn)AI代碼助手
代碼解讀
復(fù)制代碼x=new DOMMatrix;matrix=ttt;x.a=110;location='javascript'+':'+x
效果:
上面那種寫法,只能支持?jǐn)?shù)字。如果x.a處,寫了字符,那會(huì)直接語法報(bào)錯(cuò)。
new DOMMatrix
是實(shí)例化一個(gè)矩陣對(duì)象操作,具體怎么樣,說來慚愧,不是太了解,兼容性不是很好。所以這個(gè)只適合比較高的瀏覽器版本。
好了,不管滿不滿意,再上第七種了!
7、[].map.call 調(diào)用
上代碼:
js
體驗(yàn)AI代碼助手
代碼解讀
復(fù)制代碼[].map.call`${eval}\\u{74}tt\x28'JavaScript是世界上第二好的語言!CSS是第一!'\x29`
完美執(zhí)行。
ttt
函數(shù),其中一個(gè)t被\u{74}代替。
看到這里,有被轟炸到么?
準(zhǔn)備迎接最猛烈的襲擊么?
8、終極調(diào)用法
上代碼:
js
體驗(yàn)AI代碼助手
代碼解讀
復(fù)制代碼[][[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]+[[]+{}][+[]][+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[![]+[]][+[]][!+[]+!+[]+!+[]]+[!![]+[]][+[]][+[]]+[!![]+[]][+[]][+!+[]]+[[][[]]+[]][+[]][+[]]+[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]+[!![]+[]][+[]][+[]]+[[]+{}][+[]][+!+[]]+[!![]+[]][+[]][+!+[]]][[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]+[[]+{}][+[]][+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[![]+[]][+[]][!+[]+!+[]+!+[]]+[!![]+[]][+[]][+[]]+[!![]+[]][+[]][+!+[]]+[[][[]]+[]][+[]][+[]]+[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]+[!![]+[]][+[]][+[]]+[[]+{}][+[]][+!+[]]+[!![]+[]][+[]][+!+[]]]`$${[!![]+[]][+[]][+[]]+[!![]+[]][+[]][+[]]+[!![]+[]][+[]][+[]]+[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]}$```
能猜出上面的是干嘛了么?
第一次見,我也是覺的我之前學(xué)的JS,都是白學(xué)了!
直接上解釋,上面主要的做法,就是Function(ttt())
給逐個(gè)轉(zhuǎn)義了。其中[!![]+[]][+[]][+[]]
代表了t
。
[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]
代表了左括號(hào)(
。
[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]
代表了右括號(hào))
。
OK!這些就是JavaScript中平平無奇的函數(shù)調(diào)用!
請(qǐng)受用!也請(qǐng)那些舉一反三的大佬,不要另外他用哦!