【问题标题】:Override function (e.g. "alert") and call the original function?覆盖函数(例如“alert”)并调用原始函数?
【发布时间】:2012-05-12 18:01:59
【问题描述】:

我想用调用原始版本的新版本覆盖 Javascript 内置函数(类似于在许多语言中使用调用 super 的版本覆盖类上的方法)。我该怎么做?

例如...

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

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

【问题讨论】:

标签: javascript overriding


【解决方案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
    };
})();

通用方式是&lt;original_func_reference&gt;.apply(this, arguments) - 保留上下文并传递所有参数。通常,原方法的返回值也应该返回。

但是,众所周知,alert 是一个 void 函数,只接受一个参数,并且不使用 this 对象。所以,_alert(str) 在这种情况下就足够了。

注意:如果您尝试覆盖alert,IE window.alert = ... 而不是alert = ...。

【讨论】:

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

如何在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”成为“保留”词:-)

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      注意“自调用函数”,它返回一个新的函数对象(分配给window.alert 属性)。返回的新函数对象在 variable original 周围创建了一个闭包,该闭包的计算结果是 window.alert 的原始 值,它被传递给“自调用函数” .

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

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

      编码愉快。

      【讨论】:

      • 这是一个非常优雅的闭包用法。绝对是我见过的最小的封闭足迹。
      【解决方案5】:

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

      你会这样做:

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

      【讨论】:

      • 注意:这种方法不易扩展。两次调用相同的代码,你就失去了原来的方法。
      • 如果你只设置 window._alert 如果它未定义,则不会。
      猜你喜欢
      • 1970-01-01
      • 2020-12-15
      • 1970-01-01
      • 2013-06-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-22
      • 2010-10-25
      相关资源
      最近更新 更多