【问题标题】:Overriding native function?覆盖本机功能?
【发布时间】:2010-02-27 03:14:09
【问题描述】:

原生的document.createElement() 傻傻的(它只需要一个标签名,没有属性)。我怎么不能覆盖它?这怎么行不通?

var originalFunction = document.createElement;

document.createElement = function(tag, attributes) {
    var element = originalFunction(tag);

    if (attributes) {
        for (var attribute in attributes) {
            element.setAttribute(attribute, attributes[attribute]);
        }
    }

    return element;
};

问题在于,当您尝试替换本机功能时,浏览器会崩溃。由于document 不是JavaScript 原语,因此您也无法为其创建原型。见鬼。

【问题讨论】:

  • 我认为document.createElement(..) 也不太重视你。
  • 为什么不直接创建和使用自己的函数而不是覆盖原生函数?
  • @KennethJ 因为有些人仍然尝试创建标准化库或尝试在 DOM 上创建元素时执行验证代码,而无需创建命名空间和其他东西。

标签: javascript dom


【解决方案1】:

据我所知,问题是即使被引用也必须从文档中调用document.createElement() 函数。所以修改你的代码:

var element = originalFunction.call(document, tag);

【讨论】:

    【解决方案2】:

    FWIW(信息性):在某些情况下,至少在某些浏览器中,您可以覆盖“本机”方法。 Firefox 让我这样做:

    document.createElement = function(f) { alert(f); };
    

    然后在调用时会按照您的预期执行。但是您上面的整个代码块都会引发错误,至少通过 Firebug 是这样。

    从哲学上讲,您应该能够做到这一点。你当然可以重新定义 Array 对象上的方法,等等。但是 ECMAScript 没有涵盖窗口 (DOM) 方法,因此它们可能被允许依赖于实现。当然,出于安全原因,它们是这样的。

    【讨论】:

      【解决方案3】:

      为什么不直接在你自己的函数中使用该方法——按照你想要的方式编写它,永远不要再编写 document.createElement....

          document.create= function(tag, parent, attributes){
           tag= document.createElement(tag);
           for(var p in attributes){
            if(p== 'css') tag.style.cssText= attributes.css;
            else if(p== 'text') tag.appendChild(document.createTextNode(attributes.text));
            else tag[p]= attributes[p];
      
           }
          if(parent) parent.appendChild(tag);
           return tag;
          }
      
      document.create('p',document.body,{css:'font-style:italic',className:'important',title:'title',
      text:'whatever text you like'});
      

      【讨论】:

        【解决方案4】:

        据我所知,出于安全原因,您不能覆盖本机方法。对于非本地方法,这完全没有问题。

        【讨论】:

        • 在某些浏览器中,您可以覆盖一些本机方法。我还没有遇到过不能被覆盖的原生方法。
        • @JimBlackler - 仅供参考 MSIE 的控制台。 不能被覆盖,但不是出于安全原因,只是因为他们可以这样做(请参阅,ES 不涵盖控制台 :) Microsoft 再次,哈哈)
        【解决方案5】:

        没有办法覆盖它,但是如果您不害怕将非常规参数传递给本机函数,您可以做一些修改。所以关于 createElement 的事情是它成为 XML DOM 的一部分,因此您可以创建任何您想要的标记名。这就是诀窍,如果您将属性作为第一个参数(标记名)的一部分传递,用您选择的分隔符分隔它们,然后监听 DOM 的 onchange 事件,如果您的分隔符出现在任何标记,用适当的标记替换它们,例如使用 RegExp。

        【讨论】:

          【解决方案6】:

          JavaScript: Overriding alert() 中提到的代理模式应该适用于此。

          它在 jquery 文档中提到,但看起来它实际上并不依赖于 jQuery。

          更多信息在这里:http://docs.jquery.com/Types#Proxy%5FPattern

          【讨论】:

            【解决方案7】:

            试试这个。

            document.constructor.prototype.createElement = _ => `P for "pwned"`;
            
            console.log(document.createElement("P"));

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2022-01-23
              • 2016-10-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多