摘要:當(dāng)一個(gè)值為字符串,另一個(gè)值為非字符串,則后者轉(zhuǎn)為字符串。文章出自的個(gè)人博客
JavaScript 是一門(mén)弱類(lèi)型語(yǔ)言,剛接觸的時(shí)候感覺(jué)方便快捷(不需要聲明變量類(lèi)型了耶!),接觸久了會(huì)發(fā)現(xiàn)它帶來(lái)的麻煩有的時(shí)候不在預(yù)期之內(nèi)
呵呵一笑,哪有這么夸張,可能有人看過(guò)這樣一段代碼
[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+([]+[])[(![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]()[+!+[]+[!+[]+!+[]]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+![]+[![]]+([]+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+([]+[])[(![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]()[+!+[]+[!+[]+!+[]]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()
這個(gè)占了好大的篇幅哈 3167 個(gè)字符,粘貼到瀏覽器的 Console 控制臺(tái),直接彈出了 orange,隨叫隨到有不有
對(duì)于不知道原理出處的給大家一個(gè)地址:http://www.jsfuck.com/
JSFuck 的{{BANNED}}程度達(dá)到了極致,因?yàn)樗睦砟钍?Write any JavaScript with 6 Characters: []()!+
或許又有人說(shuō):這個(gè)只是搞怪的吧,實(shí)際誰(shuí)這么寫(xiě)代碼啊
說(shuō)的沒(méi)錯(cuò),當(dāng)一段代碼變得晦澀難懂的時(shí)候,甚至到上文的混亂字符(天書(shū)),卻能實(shí)現(xiàn)任意功能這就變得不可預(yù)期,也就是說(shuō) JS 代碼的安全性沒(méi)有保障
當(dāng)然本文不會(huì)研究這些無(wú)意義的字符原理是怎么實(shí)現(xiàn)的因?yàn)槿思业?Github 文檔已經(jīng)描述的特別全面了,感興趣的可以研究下:https://github.com/aemkei/jsfuck
我們聊一聊每天能看到用到的方法底層是怎么解析的,熟知轉(zhuǎn)換分成兩種一種是隱式轉(zhuǎn)換,另一種是強(qiáng)制的類(lèi)型轉(zhuǎn)換
隱式轉(zhuǎn)換當(dāng)遇到以下幾種情況,JavaScript會(huì)自動(dòng)轉(zhuǎn)換數(shù)據(jù)類(lèi)型:
不同類(lèi)型的數(shù)據(jù)進(jìn)行互相運(yùn)算
對(duì)非布爾值類(lèi)型的數(shù)據(jù)求布爾值
對(duì)非數(shù)值類(lèi)型的數(shù)據(jù)使用一元運(yùn)算符(即 "+" 和 "-")
隱式轉(zhuǎn)換為 Boolean大多數(shù)在做 if 判斷時(shí)會(huì)用到,這里只需記住六個(gè)轉(zhuǎn)換為 false,其它全部為 true
null
undefined
NaN
""
-0
+0
隱式轉(zhuǎn)換為 String字符串的自動(dòng)轉(zhuǎn)換,主要發(fā)生在加法運(yùn)算時(shí)。當(dāng)一個(gè)值為字符串,另一個(gè)值為非字符串,則后者轉(zhuǎn)為字符串。
"1" + 2 // "12" "1" + true // "1true" "1" + false // "1false" "1" + {} // "1[object Object]" "1" + [] // "1" "1" + function (){} // "1function (){}" "1" + undefined // "1undefined" "1" + null // "1null"隱式轉(zhuǎn)換為 Number
除了加法運(yùn)算符有可能把運(yùn)算子轉(zhuǎn)為字符串,其他運(yùn)算符都會(huì)把兩側(cè)的運(yùn)算子自動(dòng)轉(zhuǎn)成數(shù)值
"5" - "2" // 3 "5" * "2" // 10 true - 1 // 0 false - 1 // -1 "1" - 1 // 0 "5" * [] // 0 false / "5" // 0 "abc" - 1 // NaN +"abc" // NaN -"abc" // NaN +true // 1 -false // 0
隱式轉(zhuǎn)換的基礎(chǔ)表現(xiàn)都在這了,強(qiáng)調(diào)的是這些轉(zhuǎn)換的背后都伴隨著強(qiáng)制轉(zhuǎn)換,使用 Boolean、Number 和 String,下面重點(diǎn)講一下強(qiáng)制轉(zhuǎn)換的原理強(qiáng)制轉(zhuǎn)換
看到上面例子也許你已經(jīng)有些許疑問(wèn)了,比如上面的這個(gè) "1" + {} 怎么就輸出 1[object Object] 了呢
如上面強(qiáng)調(diào)的,你會(huì)猜測(cè)首先執(zhí)行 String({}) 得到 "[object Object]" ,然后再字符串拼接,是的我們總能得到轉(zhuǎn)換背后的實(shí)現(xiàn)原理,其實(shí)真實(shí)原理要比這個(gè)復(fù)雜,見(jiàn)下文
強(qiáng)制轉(zhuǎn)換為 Boolean這里略過(guò)因?yàn)榕c隱式轉(zhuǎn)換相同,切記 []、{} 都轉(zhuǎn)換成 true
強(qiáng)制轉(zhuǎn)換為 String基本類(lèi)型的轉(zhuǎn)換結(jié)果與隱式轉(zhuǎn)換相同,這里說(shuō)一下對(duì)象的轉(zhuǎn)換,加深上面引用例子的解析
對(duì)象轉(zhuǎn)換字符串分成三步
先調(diào)用toString方法,如果toString方法返回的是原始類(lèi)型的值,則對(duì)該值使用String方法,不再進(jìn)行以下步驟
如果toString方法返回的是復(fù)合類(lèi)型的值,再調(diào)用valueOf方法,如果valueOf方法返回的是原始類(lèi)型的值,則對(duì)該值使用String方法,不再進(jìn)行以下步驟
如果valueOf方法返回的是復(fù)合類(lèi)型的值,則報(bào)錯(cuò)
再分解這個(gè)例子
String({}) // "[object Object]"
上面代碼相當(dāng)于下面這樣
String({}.toString()) // "[object Object]"
如果 toString 方法和 valueOf 方法,返回的都不是原始類(lèi)型的值,則 String 方法報(bào)錯(cuò)
var obj = { valueOf: function () { console.log("valueOf"); return {}; }, toString: function () { console.log("toString"); return {}; } }; String(obj) // TypeError: Cannot convert object to primitive value
我們不難看出可以對(duì) toString 方法和 valueOf 方法進(jìn)行改寫(xiě),測(cè)試其先后運(yùn)行的順序也簡(jiǎn)單的多
String({toString:function(){return 3;}}) // "3" String({valueOf:function (){return 2;}}) // "[object Object]" String({valueOf:function (){return 2;},toString:function(){return 3;}}) // "3"
結(jié)果表示toString方法先于valueOf方法執(zhí)行
強(qiáng)制轉(zhuǎn)換為 Number基本類(lèi)型轉(zhuǎn)換如下
Number("123") // 123 Number("123abc") // NaN Number("") // 0 Number(false) // 0 Number(undefined) // NaN Number(null) // 0
對(duì)象轉(zhuǎn)換一樣要復(fù)雜些,與 String 唯一不同的就是 valueOf 方法在前, toString 方法在后,其它不贅述見(jiàn)上文例子。
isNaN() 并不陌生,isNaN({}) //true 的內(nèi)在轉(zhuǎn)換過(guò)程是相同的
總結(jié)其它的轉(zhuǎn)換原則還有很多,看到這我們還是不能解釋文章開(kāi)始的代碼轉(zhuǎn)換的過(guò)程,掌握這些更多是保證正常書(shū)寫(xiě)代碼規(guī)避錯(cuò)誤的發(fā)生,十分好奇的可以研究下比較特殊的轉(zhuǎn)化原則,還有好多好多。
文章出自 orange 的 個(gè)人博客 http://orangexc.xyz/
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/80724.html
摘要:是事件驅(qū)動(dòng)的,只根據(jù)用戶(hù)的操作做出相應(yīng)的反應(yīng)處理。中的數(shù)據(jù)要求帶有明確的類(lèi)型,不要求。這些小小的變化可能會(huì)產(chǎn)生嚴(yán)重的意想不到的后果,因此有必要撤銷(xiāo)這些變化。的優(yōu)勢(shì)相比于,也有一些明顯優(yōu)勢(shì)。因此在應(yīng)對(duì)大型開(kāi)發(fā)項(xiàng)目時(shí),使用更加合適。 showImg(https://segmentfault.com/img/bV1Dx7?w=740&h=322); TypeScript 和 JavaScri...
摘要:下面是用實(shí)現(xiàn)轉(zhuǎn)成抽象語(yǔ)法樹(shù)如下還支持繼承以下是轉(zhuǎn)換結(jié)果最終的結(jié)果還是代碼,其中包含庫(kù)中的一些函數(shù)。可以使用新的易于使用的類(lèi)定義,但是它仍然會(huì)創(chuàng)建構(gòu)造函數(shù)和分配原型。 這是專(zhuān)門(mén)探索 JavaScript 及其所構(gòu)建的組件的系列文章的第 15 篇。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! 如果你錯(cuò)過(guò)了前面的章節(jié),可以在這里找到它們: JavaScript 是...
摘要:的特性和性能是的超集,用于幫助的開(kāi)發(fā)。注解提供了連接元數(shù)據(jù)和功能的工具。通過(guò)在庫(kù)中提供基本信息可以調(diào)用函數(shù)或創(chuàng)建類(lèi)的實(shí)例來(lái)檢查相關(guān)元數(shù)據(jù),從而簡(jiǎn)化了對(duì)象實(shí)例的構(gòu)建。停用它會(huì)響應(yīng)跳出舊控制器的成功事件。 showImg(https://segmentfault.com/img/bVSqTU?w=850&h=460); 在Web應(yīng)用開(kāi)發(fā)領(lǐng)域,Angular被認(rèn)為是最好的開(kāi)源JavaScri...
摘要:強(qiáng)制類(lèi)型轉(zhuǎn)換本章介紹了的數(shù)據(jù)類(lèi)型之間的轉(zhuǎn)換即強(qiáng)制類(lèi)型轉(zhuǎn)換包括顯式和隱式。強(qiáng)制類(lèi)型轉(zhuǎn)換常常為人詬病但實(shí)際上很多時(shí)候它們是非常有用的。隱式強(qiáng)制類(lèi)型轉(zhuǎn)換則沒(méi)有那么明顯是其他操作的副作用。在處理強(qiáng)制類(lèi)型轉(zhuǎn)換的時(shí)候要十分小心尤其是隱式強(qiáng)制類(lèi)型轉(zhuǎn)換。 前言 《你不知道的 javascript》是一個(gè)前端學(xué)習(xí)必讀的系列,讓不求甚解的JavaScript開(kāi)發(fā)者迎難而上,深入語(yǔ)言?xún)?nèi)部,弄清楚JavaSc...
摘要:盡管等待了多年,但是最終還是發(fā)布了正式版本與上一個(gè)版本相比未有重大變化,主要著眼于部分錯(cuò)誤修復(fù)與提升。能夠?qū)惒胶瘮?shù)移入獨(dú)立線(xiàn)程中,可以看做函數(shù)的單函數(shù)簡(jiǎn)化版。不過(guò)需要注意的是,僅支持純函數(shù),其會(huì)在獨(dú)立的作用域中運(yùn)行這些函數(shù)。 showImg(https://segmentfault.com/img/remote/1460000013038757); 前端每周清單專(zhuān)注前端領(lǐng)域內(nèi)容,以對(duì)...
閱讀 2328·2021-11-22 14:56
閱讀 1460·2021-09-24 09:47
閱讀 904·2019-08-26 18:37
閱讀 2818·2019-08-26 12:10
閱讀 1522·2019-08-26 11:55
閱讀 3140·2019-08-23 18:07
閱讀 2294·2019-08-23 14:08
閱讀 605·2019-08-23 12:12