day07 Javascript 原生函数打“猴子补丁”

446 阅读2分钟

今天学到一个有趣的词:猴子补丁(monkey patched),忍不住介绍给大家。

先认识下 Javascript 原生函数

在 Javascript 中,“原生函数”(Native function) 是那些源代码被编译为原生机器码的函数。我们可以在 Javascript 标准内置对象中找到原生函数(比如 window.scroll() 、 window.fetch()) ,或者在浏览器 Web API 中找到(sessionStorage.getItem())。

由于 Javascript 的动态特性,开发者可以覆盖浏览器暴露出来的原生函数,这种技巧被我们称作“猴子补丁”。

那么,什么是“猴子补丁”呢?

猴子补丁主要用于修改浏览器内置 API 和原生函数的默认行为。这通常是添加特定功能、polyfill 特性、hook 到 API 的唯一方法,因为我们没法直接对这些 API 进行访问。

猴子补丁是个强大而危险的功能,因为你没法控制那些被你覆盖的代码:未来 JavaScript 引擎的更新可能会打破你在补丁中做出的一些假设,并导致严重的 Bug。

另外,对那些并非由你负责的代码打猴子补丁,可能会覆盖一些被其他开发者加入的猴子补丁,引入潜在的冲突。

出于以上种种,我们需要确定给定函数是否是原生函数,是否被打了猴子补丁,那么有哪些方法呢?

用 toString() 来检查函数上的猴子补丁

从控制台输出我们可以看到:默认情况下,原生函数的 toString() 返回这么一行 "function fetch() { [native code] }"

window.scroll.toString()
// 'function scroll() { [native code] }'

因此,我们可以检测输出是否包含 "[native code]" 字符串做简单的判断。

当然,如果有恶意代码绕过这个检测方法,那你就得考虑更严格的检测方式了。这些边缘情况就不多说了,感兴趣可以去研究下~