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