覆盖函数(例如“警报”)并调用原始函数?

IT技术 javascript overriding
2021-03-10 17:25:42

我想用一个调用原始函数的新版本来覆盖一个 Javascript 内置函数(类似于用一个super以多种语言调用的版本覆盖一个类上的方法)。我怎样才能做到这一点?

例如...

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

    //super.alert(str) // How do I do this bit?
}
5个回答

将原始函数的引用存储在变量中:

(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 <= 8 会引发错误alert,因此请确保您使用的是window.alert = ...而不是alert = ...

@Rob 感谢您的提醒。您是否注意到其他内置函数的 IE 问题?
2021-05-04 17:25:42
@ring0 基本上每个内置的: confirm, document, ... 如果你想拦截window.alert调用,你可以将代码包装在一个声明和定义自定义window(或alert)变量的闭包中如果您的应用程序不依赖于隐式变量声明,这将始终有效。
2021-05-05 17:25:42
@RobW 尽管这篇文章已经很老了,但只是在 IE 7.0.6002.18005 (Vista) 和 IE 8.0.6001.18702 (Win XP) 中测试了警报覆盖,并且在两者中都有效。
2021-05-05 17:25:42
@JeremyS。哦,你说得对。当我写那句话时,我使用了alert = ..... 这会引发错误。但是,如果您使用window.alert = ...,那么一切都会按预期进行。
2021-05-05 17:25:42
刚刚测试:所有主流浏览器都允许修改 global window.alert,IE <= 8 除外。在 IE 9 之前,尝试覆盖时会抛出错误alert
2021-05-08 17:25:42

没有“超级”。无论如何,创建一个闭包来“保留”原始函数对象。

请注意“自调用函数”,它返回一个新的函数对象(分配给window.alert属性)。返回的新函数对象周围产生一个闭合变量 original,其计算结果为原始window.alert,在“自主调用功能”获得通过。

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

但是,我相信某些浏览器可能会阻止alert和其他内置程序被修改...

快乐编码。

这是一个非常优雅的闭包用法。绝对是我见过的最小的闭合足迹。
2021-04-17 17:25:42

我假设您的问题是如何覆盖内置函数并仍然能够调用它。首先作为免责声明,除非您有充分的理由这样做,否则您永远不应该覆盖内置插件,因为它会使调试/测试变得不可能。

你会这样做:

window._alert = window.alert;
window.alert = function(str) { 
     if(console) console.log(str);
     window._alert(str);
}
注意:这种方法不容易扩展。两次调用相同的代码,你就失去了原来的方法。
2021-05-08 17:25:42
如果您仅设置 window._alert 未定义,则不会。
2021-05-15 17:25:42

如何在 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);
 };
};

适用于多个参数。
尝试覆盖未定义或非函数时失败。
使“superFunction”成为“保留”字 :-)

JavaScript 不使用经典的继承模型。这里有一篇很好的文章,它描述了一种编写类的方法,以便可以使用类似的语法,但它本身并不支持。