再看一下上面这张图,不难发现,这 239 个全局变量,有很多都是老朋友了,name、history、location、onclick、onerror… 这些变量明显和这只小恐龙没啥关系,打印出来纯粹是来充个数,还浪费了我找目标的时间,所以我遇到了第一个问题:如何快速找到由开发者自定义的全局变量?
假如我有一个正常的 window…不对,不用假如,新开一个空窗口不就得了 在新打开窗口的控制台,我得到了这样的结果:
也就是说,在这个恐龙快跑的小游戏里,Google 的前端工程师向 window 注入了 43 个全局变量(239-196)…
怎么把这 196 个原生的全局变量拿过来呢?复制粘贴就太 low 了,让我想想…
在原有窗口的基础上,再搞一个新窗口…这不就是 iframe 吗!iframe 虽然没有 window ,但是它有 contentWindow ,原则上来说,属性差别应该不大。所以现在只需要创建一个 iframe,拿它里面 contentWindow 的全局变量去过滤当前 window 的全局变量,就可以筛选出那多余的 43 个嫌疑人了。
于是我在控制台敲出了下面这些代码
回车!
诶,怎么是 45 个?比预期的多了 2 个,难道 window 里面还包含哪些 contentWindow 里面没有的变量吗?于是我把相同的代码拿去 url 为 about:blank 的窗口下执行了一遍,发现了罪魁祸首:
哦…原来是我给 Chrome 安装的 React 开发者工具干的好事…忽略!
我打开了先前检索到的 45(43+2) 个多余全局变量,大致扫了一眼,很快就发现了一个很可疑的选手:
Runner ,不就是这个一直在跑步的小恐龙吗
看看它是个什么货色,无脑 typeof 一下:
emmm居然是函数,哦?函数,首字母还大写,这熟悉的味道,这不就是个构造函数吗!正所谓,构造函数的宝藏都在 prototype 里,在观察了一遍这个宝藏之后,我发现了一个名为 gameOver 的方法,
这个函数名,难不成它就是那个让小恐龙去死的方法?既然这样,呵,我反手就把它用空函数覆盖了。于是…
真的是…
然后我又发现了另一个有趣的方法:
顾名思义,这是用来给小恐龙设置奔跑速度的方法,但是怎么调用呢?由构造函数创建的实例对象,可通过原型链访问构造函数 prototype 上的变量和方法,也就是说,如果能找到这个小恐龙对应的实例,那么就能直接调用这个 setSpeed 方法了。既然 Google 的前端工程师已经把这么多变量搞到全局了,那么…会不会也在全局存储了这个小恐龙实例?我重新审视了一遍那 43 个多出来的全局变量,并没有找到。我下意识地随手输入了一下这个 Runner 构造函数,真是山重水复疑无路柳暗花明又一村呐:
最后
大厂面试问深度,小厂面试问广度,如果有同学想进大厂深造一定要有一个方向精通的惊艳到面试官,还要平时遇到问题后思考一下问题的本质,找方法解决是一个方面,看到问题本质是另一个方面。还有大家一定要有目标,我在很久之前就想着以后一定要去大厂,然后默默努力,每天看一些大佬们的文章,总是觉得只有再学深入一点才有机会,所以才有恒心一直学下去。