javascript - 覆盖对象原型(prototype)并不允许任何进一步的覆盖

标签 javascript

我正在尝试编写一个库来拦截所有 XMLHttpRequest 调用并在最终发送请求之前做一些事情,方法是覆盖其原型(prototype),例如:

var original_open = XMLHttpRequest.prototype.open;    
XMLHttpRequest.prototype.open = function() {
    // my own override logic here before running the original function
    original_open.apply(this, arguments);
};

问题是,我想保证当有人使用这个库时,网页上的任何其他代码都不可能重新覆盖这个效果。

因为否则,使用这个库的网站可以动态加载另一段 JS 代码,它会再次简单地覆盖 XMLHttpRequest.prototype.open,而这个库的全部目的就是禁止这样做。

我考虑过在覆盖后立即使用 Object.freeze() 卡住原型(prototype),这样其他代码就无法覆盖我自己的覆盖。代码看起来像这样:

var original_open = XMLHttpRequest.prototype.open;    
XMLHttpRequest.prototype.open = function() {
    // my own override logic here before running the original function
    original_open.apply(this, arguments);
};
Object.freeze(XMLHttpRequest.prototype);

我的预期是,如果同一页面上的另一段代码试图重新覆盖我自己的覆盖,它将失败,因为原型(prototype)已被卡住。

我的问题:

  1. 这是这个问题的正确解决方案吗?
  2. 这真的安全吗? (没有漏洞)?

最佳答案

不要卡住原型(prototype)。这将导致开发人员感到沮丧、无法解释的错误,并且没有人使用您的库。您无法知道哪些其他库会修改该方法,以及它们将如何修改,这会导致您为无穷无尽的边缘情况编写代码。坚持最佳实践,并假设开发人员正在做出明智、兼容的库选择。

由于客户端代码的性质,您将不得不假设其他专业图书馆会遵循最佳实践。如果 5 个库都使用您使用的约定修改原型(prototype)方法,则所有 5 个库将协同工作。

例如,这两个覆盖只是一起工作:

var old1 = Document.prototype.querySelector;
Document.prototype.querySelector = function(...args) {
  console.log('Override 1');
  return old1.call(this, ...args);
};

var old2 = Document.prototype.querySelector;
Document.prototype.querySelector = function(...args) {
  console.log('Override 2');
  return old2.call(this, ...args);
};

let p = document.querySelector('body');

console.log(p);

关于javascript - 覆盖对象原型(prototype)并不允许任何进一步的覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47295812/

相关文章:

javascript - 如何使用es6的filter或reduce来破坏对象属性?

javascript - 图像旋转 - 根据图像高度和宽度调整 Canvas 大小

javascript - 下划线代码在网页上不显示任何内容

JavaScript 子方法

javascript - 我如何创建一个 weka 类型的接口(interface)

javascript - 如何使用数据库表中的特定 ID 或变量登录

javascript - 收集满足特定条件的所有对象键的列表

javascript - PHP/Javascript,通过给定的代理查看外部页面(URL)?

javascript - 在 Node js中将JSON.gz转换为JSON

javascript - 如何使用 CSS 创建标题上显示的 Angular ?