覆盖原生功能?

时间:2010-02-27 03:14:10

标签: javascript dom

本机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原语,因此您也无法为其创建原型。 WTF。

7 个答案:

答案 0 :(得分:10)

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

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

答案 1 :(得分:3)

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

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

然后在调用时按预期执行。但是你的整个代码块都会抛出一个错误,至少是通过Firebug。

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

答案 2 :(得分: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'});

答案 3 :(得分:1)

据我所知,出于安全原因,您无法覆盖原生方法。对于非本地方法,它根本没问题。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

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

此处有更多信息:http://docs.jquery.com/Types#Proxy%5FPattern

答案 6 :(得分:0)

尝试一下。

document.constructor.prototype.createElement = _ => `P for "pwned"`;

console.log(document.createElement("P"));