如何覆盖从 javascript 中的模块返回的 class 中的函数

How to override a function in a class being returned from module in javascript

我在一个模块中有一个日志记录 class,其中包含一个静态函数 return 自身的一个实例,因此简化版本如下所示:

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 但我认为问题是原始基础 class 只是从静态函数 returned 所以我的重写函数不是电话:

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

const dblogging = {
  Logger: dblogger
};

export default dblogging;

您需要从 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 class 进行更改,您可以更改 createFromConfig() 以允许指定 class,然后您可以使用您的子class.

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

我相信你真的想在你的方法中使用这个.constructor.prototype.错误:

class Logger{
  static createFromConfig(key){   
    return new Logger(key);
  }
  info(message){
    // do logging stuff
  }
  debug(message){
    // do logging stuff
  }
  error(message){
    return message;
    // do logging stuff
  }
}
class logging extends Logger{
}
const log = logging.createFromConfig('test');
log.error = function(message){
  console.log(this.constructor.prototype.error('Logger message here'));
  console.log(message);
}
log.error('within log');