奇妙的一行JS程式码之完整解析

这段程式是我在网路上无意间看到的,如果你把这段程式码贴到开发人员工具的 console 会看到像下图一样出现一堆框线XDD
[].forEach.call($$("*"),function(a){a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)})

那我们就来看懂这段程式到底在做啥,不过简单的来说就是抓取页面所有元素并且给予它们随机颜色的边框。

我们先看到 [].forEach.call($$("*"), function(a){...}) 的部分:

$$('') 意义等同于 document.querySelectorAll(''),可以参考以下连结:
https://developers.google.com/web/tools/chrome-devtools/console/utilities#queryselectorall

[] 等同于 Array.prototype。为阵列 Array 的原型,它定义了阵列的一系列方法,从附图可以知道 Array.prototype 包括了许多我们在操作阵列会用到的方法。

顺便一提,这边要有原型和继承的概念才比较了解在做啥

了解以上两点后,原本的程式就可以看做:
Array.prototype.forEach.call(document.querySelectorAll('*'), function(a){...})

那么为何不使用 document.querySelectorAll('*').forEach(function() {}); 去选择所有元素呢,这样不是比较浅显易懂吗?那是因为 document.querySelectorAll() 会回传一组 NodeList,而 NodeList 在比较旧的浏览器可能不支援搭配 forEach 这样的写法(目前比较新的浏览器已经可以这样写了),因此用阵列搭配 forEach 和 call 来选取所有页面元素。

补充:

关于 NodeList: 它包括了DOM元素节点,文字和属性,以<div id="title">Hello world</div> 为例,DOM元素节点就是<div>,文字为Hello world,属性为id="title"
mozilla上NodeList的介绍:
https://developer.mozilla.org/en-US/docs/Web/API/NodeList

forEach() + call() 的使用参考:
https://stackoverflow.com/questions/16053357/what-does-foreach-call-do-in-javascript

接着我们来看 function 里面的这段内容:
function(a){a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)}

在此就是将刚刚透过 document.querySelectorAll('*') 取到的NodeList一个个传入这个函式,并为它们加上宽度 1px 的框线,#"+(~~(Math.random()*(1<<24))).toString(16) 产生的就是16进位的色码。

(1<<24)的部分,就是将1变成1000...总共24位数,而且为二进位制的型态,转为十进位此数字将为16,777,216
可以参考:
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#%E4%BD%8D%E5%85%83%E4%BD%8D%E7%A7%BB%E9%81%8B%E7%AE%97%E5%AD%90

备注: 这边要有进位制概念才看得懂在做啥

~~ 这个符号,效用几乎相等于 Math.floor() (在正整数的情况下两者结果都会相等,负数则不会),~ 它就是位元运算子的其中一个,而 ~~ 就是做两次 NOT 运算
~(4.5) // -5~(-4.5) // 3~~(4.5) // 4~~(-4.5) // -4

参考资料:
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#(%E4%BD%8D%E5%85%83_NOT)

最后是 toString(),这相当好理解就是将前面的一串东西转为字串,()里面的参数则是代表数字的进位制。

因此 (~~(Math.random()*(1<<24))).toString(16) 这段我们可以理解就是取 0~16,777,216 的乱数并去掉小数点,再转为16进位的数字再变成字串,最后得到16进位的随机色码,例如 #FFFFFF 白色,也因此我们才会在输入整段程式码的网页看到一堆五颜六色的边框XDD。

最后的小心得就是短短的一段程式码里面竟然包含了不少观念,写出这段程式码的人实力真的坚强,自己也查到是 Google 的工程师 Addy Osmani 写的,也附上这段程式来源的 Github Gist 给大家看看:
https://gist.github.com/addyosmani/fd3999ea7fce242756b1
有机会也可以逛逛这位大神的 Github,感受一下所谓的大神是什么样子哈哈哈。


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章