一個陽光明媚的週末,透光的窗簾把我從睡夢中叫醒,大腦說今天是週六,能夠慵懶個一上午,因而開心地打開個人 Mac 準備看兩集 Rick and Morty 再起牀洗漱。前端
我火燒眉毛打開了對應的網站,發現瀏覽器提示 No internet,這才發現由於個人動做太過於行雲流水,電腦還沒來得及連上 wifichrome
因而我決定重溫一下這款經典的遊戲。數組
https://www.qq.com/video/q315...瀏覽器
科普:Chrome 瀏覽器是 Google 家的官方瀏覽器,使用體驗全世界南波萬。當用戶在無網絡時訪問某一網址,瀏覽器會提示「無網絡連接」(也就是上面這張圖),按下空格鍵,就會喚醒一個小恐龍跑步刷分的遊戲。
若是在有網絡鏈接時也想玩的話,能夠直接在地址欄輸入: chrome://dino
出於職業自己的敏感和好奇,我忽然心生疑問:這應該是用 JS 作的吧?網絡
我順勢打開控制檯,不如先看一下全部的全局變量?前端工程師
太多了,我可沒這個耐心...ide
我中止了操做,開始思考這一切的可行性:函數
也就是說,若是沒有在全局變量裏找到那個對象,我就能夠選擇性放棄了。工具
再看一下上面這張圖,不難發現,這 251 個全局變量,有不少都是老朋友了,name、history、location、onclick、onerror... 這些變量明顯和這隻小恐龍沒啥關係,打印出來純粹是來充個數,還浪費了我找目標的時間,因此我遇到了第一個問題:如何快速找到由開發者自定義的全局變量?網站
假如我有一個正常的 window...不對,不用假如,新開一個空窗口不就得了!
在新打開窗口的控制檯,我獲得了這樣的結果:
也就是說,在這個恐龍快跑的小遊戲裏,Google 的前端工程師向 window 注入了 最多 55 個全局變量(251-196)...
爲何說最多 55 個?由於 Chrome 的版本以及安裝的 Chrome 插件都會影響全局變量的個數,好比 React 開發者工具就會向 window 中注入兩個全局變量。
因而問題來到了:怎麼把這 55 個被注入的全局變量拿過來呢?複製粘貼以後再一個一個比對?太 low 了,讓我想一想...
在原有窗口的基礎上,再搞一個新窗口...這不就是 iframe 嗎!iframe 雖然沒有 window,可是它有 contentWindow,原則上來講,屬性差異應該不大。因此如今只須要建立一個 iframe,拿它裏面 contentWindow 的全局變量去過濾當前 window 的全局變量,就能夠篩選出那多餘的 55 個「嫌疑人」了。
思路有了,寫代碼也就容易多了:
在控制檯輸入這些代碼後會車,我獲得了這樣的結果:
這下篩選出了 45 個全局變量。
45 個總比 200 多個好找一些,打開這個數組,我發現了一個命名很可疑的傢伙:
Runner,不就是那個「奔跑着的小恐龍」嗎(壞笑)?
那就看看它究竟是個什麼貨色!
emmm竟然是函數,哦?函數,首字母還大寫,這熟悉的味道,這不就是個構造函數嗎!正所謂,構造函數的寶藏都在 prototype 裏,在觀察了一遍這個寶藏以後,我發現了一個名爲 gameOver 的方法,
這個函數名,難不成它就是那個讓小恐龍去死的方法?既然這樣,呵,我反手就把它用空函數覆蓋了。因而...
https://www.qq.com/video/n315...
真的是...
而後我又發現了另外一個有趣的方法:
顧名思義,這是用來給小恐龍設置奔跑速度的方法,可是怎麼調用呢?由構造函數建立的實例對象,可經過原型鏈訪問構造函數 prototype 上的變量和方法,也就是說,若是能找到這個小恐龍對應的實例,那麼就能直接調用這個 setSpeed 方法了。既然 Google 的前端工程師已經把這麼多變量搞到全局了,那麼...會不會也在全局存儲了這個小恐龍實例?我從新審視了一遍那 43 個多出來的全局變量,並無找到。我下意識地隨手輸入了一下這個 Runner 構造函數,真是山重水複疑無路柳暗花明又一村吶:
我甚至都不須要看 Runner 函數的所有代碼,就知道原來實例被保存在一個名叫 instance_ 的 Runner 自身屬性裏,論起好變量名的重要性,行,那我就不客氣了,直接調用!
因而乎...
https://www.qq.com/video/f315...
當我凝視着這個飛奔的無敵小恐龍時,我忽然以爲...一切變得...
若是想要得到原版更騷氣的閱讀體驗,歡迎點擊這個傳送門(獲取更加完整的閱讀體驗)。