1、一行程式碼視覺化CSS盒子佈局
[].forEach.call($$("*"),function(a){a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)})
原始碼解讀
首先我們把程式碼格式化一下:
[].forEach.call($$("*"), function(a){ a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16) } )
1、選取頁面所有DOM元素
$$()相當於document.querySelectorAll(),傳回的是一個NodeList物件數組,現代瀏覽器幾乎都支援
2、循環遍歷DOM元素
$$("*")`將所有的`DOM`元素轉換為`NodeList`對象,但這並不是一個JS數組,所以不能直接使用`$$("*").forEach()方法來進行迭代,但是我們可以透過call或apply方法來使用forEach
[].forEach.call等價於Array.prototype.forEach.call,不過前者位元組數更少
3、為元素添加outline
為什麼不使用border而是使用outline的原因在於:border在CSS盒子模型之內,會影響頁面的整體佈局,而outline在CSS盒子模型之外,不會影響頁面的版面
4、產生隨機顏色函數
(~~(Math.random()*(1<<24))).toString(16)
隨機顏色區間:
最小:000000,轉為十進位為0
最大:ffffff,轉為十進位為256*256*256 = 16777216 1<<24)
Math.random()傳回0~1的浮點數,Math.random()*(1<<24)回傳的的即是(0,16777216)之間的浮點數,使用~ ~去除浮點數的小數部分,再透過toString(16)就轉換成十六進位的顏色值了
效果圖
點擊預覽https://gist.github.com/addyosmani/fd39975fce
2、一行能裝B的JS代碼
(!(~+[])+{})[--[~+""][+[]]*[~+[]]+~~!+[]]+({}+[])[[~!+[]]*~+[]]
上面一行神奇的程式碼,執行效果卻出人意料,請看下圖:
源碼解讀
源碼的優先順序以及JS的型別轉換
`~~`位运算符,进行类型转换,转换成数字,等同于`Math.floor()`,将浮点数变成整数 首先我们看`(!(~+[])+{})` `+[]` => `+""` => `0` `~+[]` => `-1` `!(~+[])` => `false` `(!(~+[])+{})` => `"false[object Object]"` 接着看`[--[~+""][+[]]*[~+[]]+~~!+[]]` `[+[]]` => `[0]` `[~+""]` => `[~0]` => `[-1]` `[~+""][+[]]` => `[-1][0]=>-1` `--[~+""][+[]]` => `-2` `[~+[]]` => `[-1]` `--[~+""][+[]]*[~+[]]` => `-2*[-1]` => `2` `~~!+[]` => `~~!0` => `~~true` => `1` `[--[~+""][+[]]*[~+[]]+~~!+[]]` => `[2+1]` => `[3]` 这样左侧`(!(~+[])+{})[--[~+""][+[]]*[~+[]]+~~!+[]]` => `"false[object Object]"[3]` => `"s"` 再看右侧`({}+[])[[~!+[]]*~+[]]` `({}+[])` => `"[object Object]"` `[~!+[]]` => `[~!0]` => `[~true]` => `[-2]` `~+[]` => `-1` `[[~!+[]]*~+[]]` => `[[-2]*-1]` => `[2]` `({}+[])[[~!+[]]*~+[]]` => `"[object Object]"[2]` => `"b"`