首页 > 解决方案 > 如何覆盖从javascript中的模块返回的类中的函数

问题描述

我在一个模块中有一个日志类,它包含一个返回自身实例的静态函数,因此简化版本如下所示:

Class Logger {

    static createFromConfig(key) {   
      return new Logger(key);
    }

    info(message) {
      // do logging stuff
    }

    debug(message) {
      // do logging stuff
    }

    error(message) {
      // do logging stuff
    }
}

这在我们的代码库中的许多地方都有使用,例如:

    import logging from 'logging';
    const log = logging.Logger.createFromConfig('keyname');
    log.info('App starting');

在一个项目中,我希望为错误函数添加一些额外的功能,而不必更改任何调用它的地方的代码。所以像

log.error = () => {
    // do my extra stuff here
    log.error() // call the original error function
}

我尝试过像下面这样扩展类,但我认为问题是原始基类只是从静态函数返回,所以我的覆盖函数没有被调用:

class dblogger extends logging.Logger {
  error(...args) {
   // do my extra stuff here 
    super.error();
  }
}

const dblogging = {
  Logger: dblogger
};

export default dblogging;

标签: javascriptclassinheritanceoverridingfactory

解决方案


您需要从Logger原型中调用原始方法。

function getdblogger(keyname) {
    const log = logging.Logger.createFromConfig(keyname);
    log.error = function(message) {
        // do my extra stuff here
        Logger.prototype.error.call(this, message) // call the original error function
    }
    return log;
}

请注意,您必须使用普通函数而不是箭头函数才能获得this.

如果您可以对原始Logger类进行更改,您可以更改createFromConfig()以允许指定类,然后您可以使用您的子类。

Class Logger {

    static createFromConfig(key, loggerClass = Logger) {   
      return new loggerClass(key);
    }

    info(message) {
      // do logging stuff
    }

    debug(message) {
      // do logging stuff
    }

    error(message) {
      // do logging stuff
    }
}

然后在您的文件中:

const log = logging.Logger.createFromConfig('keyname', dblogger);

推荐阅读