Переопределение собственной функции?

Нативный 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.

Ответы

Ответ 1

Насколько я могу судить, проблема заключается в том, что вызов функции document.createElement(), даже если он ссылается, должен быть из документа. Поэтому измените свой код:

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

Ответ 2

FWIW (информационный): вы можете переопределить "родные" методы, в некоторых случаях, и, по крайней мере, в некоторых браузерах. Firefox позволяет мне это сделать:

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

Что тогда делает, как вы ожидаете, когда вызывается. Но весь ваш блок кода выше порождает ошибку, по крайней мере через Firebug.

Философски, вы должны это сделать. Вы можете, скажем, переопределить методы объекта Array и т.д. Но методы окна (DOM) не покрываются ECMAScript, и поэтому они, вероятно, могут быть зависимыми от реализации. И, конечно же, они так по соображениям безопасности.

Ответ 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

Насколько я знаю, вы не можете переопределять собственные методы по соображениям безопасности. Для не-родных методов это вообще не проблема.

Ответ 5

Невозможно переопределить это, но вы можете немного взломать, если не будете бояться передавать не обычные параметры в нативную функцию. Итак, идея createElement заключается в том, что его роль будет частью XML DOM, таким образом, вы можете создать любой тэг, который вы хотите. И вот трюк, если вы передаете свои атрибуты как часть первого параметра (тэг), разделив их на разделители по вашему выбору, а затем прослушав событие onchange в DOM и если ваши разделители представлены в любом тег, замените их на правильную разметку, например, с помощью RegExp.