Переопределить функцию (например, "предупреждение") и вызвать исходную функцию?

Я хотел бы переопределить встроенную функцию Javascript с новой версией, которая вызывает оригинал (аналогично переопределению метода в классе с версией, которая вызывает super на многих языках). Как я могу это сделать?

Например...

window.alert = function(str) {
    //do something additional
    if(console) console.log(str);

    //super.alert(str) // How do I do this bit?
}

Ответ 1

Сохраните ссылку на исходную функцию в переменной:

(function() {
    var _alert = window.alert;                   // <-- Reference
    window.alert = function(str) {
        // do something additional
        if(console) console.log(str);
        //return _alert.apply(this, arguments);  // <-- The universal method
        _alert(str);                             // Suits for this case
    };
})();

Универсальный способ <original_func_reference>.apply(this, arguments) - сохранить контекст и передать все аргументы. Обычно возвращаемое значение исходного метода также должно быть возвращено.

Однако он знал, что alert является функцией void, принимает только один аргумент и не использует this объект. Итак, _alert(str) достаточно в этом случае.

Примечание. IE <= 8 выдает ошибку, если вы пытаетесь перезаписать alert, поэтому убедитесь, что вы используете window.alert =... вместо alert =...

Ответ 2

Нет "супер". Во всяком случае, создайте закрытие, чтобы "сохранить" вокруг исходного объекта функции.

Обратите внимание на функцию "self invoking", которая возвращает новый объект-объект (которому присвоено свойство window.alert). Новый возвращаемый объект-функция создает замыкание вокруг original переменной, которое вычисляет исходное значение window.alert которое было передано в функцию "self invoking".

window.alert = (function (original) {
  return function (str) {
    //do something additional
    if(console) {
      console.log(str)
    }
    original(str)
  }
})(window.alert)

Тем не менее, я считаю, что некоторые браузеры могут предотвратить изменение alert и других встроенных модулей...

Счастливое кодирование.

Ответ 3

Я предполагаю, что ваш вопрос заключается в том, как вы перезаписываете встроенный и все еще можете его назвать. Прежде всего, как отказ от ответственности, вы никогда не должны перезаписывать встроенные вложения, если у вас нет веских оснований для этого, поскольку это сделает невозможным отладки/тестирование.

Вот как вы это сделаете:

window._alert = window.alert;
window.alert = function(str) { 
     if(console) console.log(str);
     window._alert(str);
}

Ответ 4

Как сделать простое классическое наследование в Javascript:

SuperClass.call(this) // inherit from SuperClass (multiple inheritance yes)

Как переопределить функции:

this.myFunction = this.myFunction.override(
                    function(){
                      this.superFunction(); // call the overridden function
                    }
                  );

Функция переопределения создается следующим образом:

Function.prototype.override = function(func)
{
 var superFunction = this;
 return function() 
 {
  this.superFunction = superFunction;
  return func.apply(this,arguments);
 };
};

Работает с несколькими аргументами.
Сбой при попытке переопределить неопределенные или нефункции.
Делает "суперфункцию" "зарезервированным" словом :-)

Ответ 5

JavaScript не использует классическую модель наследования. Здесь есть хорошая статья, в которой описывается способ написания ваших классов, чтобы можно было использовать аналогичный синтаксис, но он не поддерживается.