如何重写一个方法以拦截对此方法的任何调用?

问题描述 投票:0回答:1

在这个小部件中有一个功能

isPermitted()
。我如何拦截它并覆盖它。

我使用以下拦截其他函数

isPermittedDomain
等,但无法覆盖
isPermitted
函数。有什么建议吗?

这是我试图拦截并覆盖的函数:

n.prototype.isPermitted = function (t) {var n = !this.direct || 'OW2017' !== e.AppSettings.omo_username;
return !n && t && this.onFail(new e.ErrorMessage({ error: 'FEED_NOT_PERMITTED' })), n;
};

我的代码:

function intercept(obj, prop, callback) {
  var oldVal = null;
  Object.defineProperty(
    obj, prop, {
      get: function() {
        return oldVal;
      },
      set: function(newVal) {
        callback.call(this, newVal);
        oldVal = newVal;
      },
      enumerable: true,
      configurable: true
    });
};

intercept(Opta, 'Subscriptions', function(Subscriptions) {
  Subscriptions.isPermittedDomain = function() {
    return true;
  };
  intercept(Subscriptions, 'feeds', function(feeds) {
    const t = Opta.Trans.loadTerms({
      term_set_id: Opta.Trans.mapSportIdToTerms(1)
    });
    Opta.when(t).done(startReact);
  });
});
javascript function design-patterns interceptor method-modifier
1个回答
1
投票

通过将拦截处理程序包装在原始(原型)

isPermitted
方法周围来直接提供拦截处理的方法怎么样?为了方便起见(包装模式的代码重用),人们将使用立即调用的箭头函数表达式。

// n.prototype.isPermitted = function (t) {
//   var n = !this.direct || ('OW2017' !== e.AppSettings.omo_username);
// 
//   return !n && t && this.onFail(new e.ErrorMessage({
//     error: 'FEED_NOT_PERMITTED'
//   })), n;
// };

// test code based on the OP's provide exampe.

class N {
  direct = true;

  isPermitted(t) {
    // const n = !this.direct || 'OW2017' !== e.AppSettings.omo_username;
    const n = !this.direct;

    // return !n && t && this.onFail(new e.ErrorMessage({
    //   error: 'FEED_NOT_PERMITTED'
    // })), n;
    if (!n && t) {
      this.onFail(new Error('FEED_NOT_PERMITTED'));
    }
    return n;
  }

  onFail(error) {
    console.log({ "error.message": error.message });
  }
}

function handleIsPermittedInterception(proceed, args, target) {
  /**
   *  - implement all functionality which is specific to the
   *    interception of the original `isPermitted` method.
   *
   *    - one does get passed in ...
   *
   *      - the original `isPermitted` method as `proceed`.
   *      - the method's arguments as a real arrray as `args`.
   *      - the method's `this` context as `target`.
   */
  console.log('+++ interception handling :: begin +++');
  console.log({ args, target, proceed });

  // the intercepted sole `t` parameter.
  const [ t ] = args;

  // implement e.g. handling upon `t`'s value.
  console.log({ t });

  // invocation of the original method within its correct context.
  const intermediateResult = proceed.apply(target, args);

  // implement e.g. handling upon the `intermediateResult`'s value.
  console.log({ intermediateResult });
  
  console.log('--- interception handling :: end ---\n\n\n');

  return intermediateResult // or any implementation specific value.
}

N.prototype.isPermitted = ((proceed, interceptor) => {

  // - wrap the handling of the interception
  //   around the original `isPermitted` method.
  return function (...args) {

    // - forwarding call wich passes all necessary
    //   values to the provided intercetion handler.
    return interceptor(proceed, args, this);
  };
})(N.prototype.isPermitted, handleIsPermittedInterception);

const n = new N;
console.log('n.isPermitted(true) ...', n.isPermitted(true));
.as-console-wrapper { min-height: 100%!important; top: 0; }

© www.soinside.com 2019 - 2024. All rights reserved.