Вопрос по javascript – Отменить функцию (например, «оповещение») и вызвать исходную функцию?

20

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

Например...

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

    //super.alert(str) // How do I do this bit?
}
Я удалил & quot; OO & quot; и "суперкласс" теги, потому что они не применяются. Но этот вопрос касается насмешек "супер" в JavaScript:stackoverflow.com/questions/6885404/javascript-override-methods user166390
Показывает главное предупреждение:stackoverflow.com/questions/1729501/javascript-overriding-alert user166390
Аналогичный, но чуть более сложный случай:stackoverflow.com/questions/296667/… user166390

Ваш Ответ

5   ответов
18

keep & quot; вокруг оригинальной функции-объекта.

Обратите внимание на «функцию самозапуска». который возвращает новый объект-функцию (который назначенwindow.alert имущество). Новый возвращенный объект-функция создает замыкание вокругvariable original который оценивает к оригиналуvalue изwindow.alert это было передано в «самопризывающую функцию».

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

Однако яbelieve некоторые браузеры могут помешатьalert и другие встроенные модули от изменения ...

Удачного кодирования.

Это очень элегантное использование крышки. Определенно самый маленький след закрытия, который я когда-либо видел.
5

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

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

window._alert = window.alert;
window.alert = function(str) { 
     if(console) console.log(str);
     window._alert(str);
}
Нет, если вы только установите window._alert, если он не определен.
Примечание: этот подход не является легко расширяемым. Вызовите один и тот же код дважды, и вы потеряли исходный метод.
2

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);
 };
};

Работает с несколькими аргументами.
Fails when trying to override undefined or nonfunctions.
Делает "суперфункцию" "зарезервировано" слово :-)

42

(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 является пустой функцией, принимает только один аргумент и не используетthis объект. Так,_alert(str) достаточно в этом случае.

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

DEMO:jsbin.com/agucin
+1 за указаниеapply.
Только что протестировано: все основные браузеры позволяют модифицировать глобальныеwindow.alert, за исключением IE & lt; = 8. До IE 9 при попытке перезаписи была выдана ошибка.alert.
@Rob Спасибо за хедз-ап. Вы заметили проблему IE с другими встроенными функциями?
@ ring0 В основном каждый встроенный:confirm, document... Если вы хотите перехватитьwindow.alert звонки, вы можете обернуть код в закрытие, где пользовательскийwindow (или жеalert) переменная объявлена и определена. Это всегда будет работать, если ваше приложение не использует неявное объявление переменных.
1

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

К сожалению. Спасибо, исправлено.
ссылка на статью неверна, пожалуйста, отредактируйте.

Похожие вопросы