【问题标题】:Recovering built-in methods that have been overwritten恢复已被覆盖的内置方法
【发布时间】:2012-01-24 17:03:26
【问题描述】:

假设我们的脚本包含在网页中,而之前的脚本(已经执行)是这样做的:

String.prototype.split = function () {
    return 'U MAD BRO?';
};

所以,split 字符串方法已被覆盖。

我们想使用这个方法,所以我们需要以某种方式恢复它。当然,我们可以只定义我们自己的这个方法的实现并使用它。但是,为了这个问题,我们只是说我们真的想恢复浏览器对该方法的实现。

因此,浏览器有一个split 方法的实现(我相信在本机代码中),并且每当加载新网页时,这个实现都会分配给String.prototype.split

我们想要那个实现!我们希望它回到String.prototype.split

现在,我已经想出了一个解决方案 - 这是一个 hack,它似乎可以工作,但它可能有缺陷,我需要测试一下......所以,与此同时,你能想出有解决这个问题的办法吗?

【问题讨论】:

  • @ЖΞЖ 使用 iframe,由 Raynos 发布。这个问题的灵感来自this answer 我过去的一个问题......

标签: javascript browser theory


【解决方案1】:
var iframe = document.createElement("iframe");
document.documentElement.appendChild(iframe);
var _window = iframe.contentWindow;
String.prototype.split = _window.String.prototype.split;
document.documentElement.removeChild(iframe);

使用 iframe 从宿主对象中恢复方法。

注意这种方法有陷阱。

"foo".split("") instanceof Array // false
"foo".split("") instanceof _window.Array // true

解决此问题的最佳方法是永远不要使用instanceof

另请注意,var _split = String.prototype.split 在顽皮脚本之前作为<script> 标记或不包括顽皮脚本显然是更好的解决方案。

【讨论】:

  • 你能想到这种方法有什么缺陷吗?会不会有问题,比如instanceof 运算符,因为这些方法“属于”外部构造函数...?
  • @ŠimeVidas 缺陷是特定于实现的。 .split 返回一个数组,它是 window.Array_window.Array 的实例
  • 根据this test,结果数组在Firefox和Safari中是window.Array的实例,而在其他浏览器中是_window.Array的实例。
  • 我猜在可能存在 anything 可写的潜在敌对环境中,无法访问函数的原始版本,即 Object.defineProperty 和/或 Object.freeze已修补——包括document.createElementwindow.open 等?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-15
  • 1970-01-01
  • 2014-04-07
相关资源
最近更新 更多