当前位置:  开发笔记 > 编程语言 > 正文

如何在Javascript中包装函数?

如何解决《如何在Javascript中包装函数?》经验,为你挑选了2个好方法。

我正在为我的一个应用程序编写一个全局错误处理"模块".

我想要的一个功能是能够使用Try {} Catch {}块轻松包装函数,以便对该函数的所有调用将自动具有将调用我的全局日志记录方法的错误处理代码.(避免使用try/catch块在任何地方污染代码).

然而,这稍微超出了我对Javascript,.call和.apply方法以及"this"关键字的低级功能的理解.

我根据Prototype的Function.wrap方法编写了这段代码:

Object.extend(Function.prototype, {
  TryCatchWrap: function() {
    var __method = this;
    return function() {
            try { __method.apply(this, arguments) } catch(ex) { ErrorHandler.Exception(ex); }
    }
  }
});

使用方式如下:

function DoSomething(a, b, c, d) {
    document.write(a + b + c)
    alert(1/e);
}

var fn2 = DoSomething.TryCatchWrap();
fn2(1, 2, 3, 4);

该代码完美无缺.它打印出6,然后调用我的全局错误处理程序.

我的问题是......当我正在包装的函数在一个对象中时它是否会破坏某些东西,它会使用"this"运算符?我有点担心,因为我打电话.在那里传递一些东西,我担心这可能会破坏一些东西.



1> Eugene Lazut..:

我个人而不是污染内置对象,我会使用装饰技术:

var makeSafe = function(fn){
  return function(){
    try{
      return fn.apply(this, arguments);
    }catch(ex){
      ErrorHandler.Exception(ex);
    }
  };
};

你可以像这样使用它:

function fnOriginal(a){
  console.log(1/a);
};

var fn2 = makeSafe(fnOriginal);
fn2(1);
fn2(0);
fn2("abracadabra!");

var obj = {
  method1: function(x){ /* do something */ },
  method2: function(x){ /* do something */ }
};

obj.safeMethod1 = makeSafe(obj.method1);
obj.method1(42);     // the original method
obj.safeMethod1(42); // the "safe" method

// let's override a method completely
obj.method2 = makeSafe(obj.method2);

但如果您确实想要修改原型,可以这样写:

Function.prototype.TryCatchWrap = function(){
  var fn = this; // because we call it on the function itself
  // let's copy the rest from makeSafe()
  return function(){
    try{
      return fn.apply(this, arguments);
    }catch(ex){
      ErrorHandler.Exception(ex);
    }
  };
};

显而易见的改进是参数化makeSafe(),以便您可以指定在catch块中调用哪个函数.


是的:您将"this"和原始参数传递给包装方法.但是你没有返回它的结果,使得包装不完整.但是如果你包装一个不返回值的函数也没关系.

2> mikemaccana..:

2017答案:只需使用ES6.给出以下演示功能:

var doThing = function(){
  console.log(...arguments)
}

您可以创建自己的包装函数而无需外部库:

var wrap = function(someFunction){
  var wrappedFunction = function(){
    var args = [...arguments].splice(0)
    console.log(`You're about to run a function with these arguments: \n     ${args}`)
    return someFunction(args)
  }
  return wrappedFunction
}

正在使用:

doThing = wrap(doThing)

doThing('one', {two:'two'}, 3)

2016答案:使用wrap模块:

在下面的示例中,我正在包装process.exit(),但这与任何其他功能(包括浏览器JS)也很愉快.

var wrap = require('lodash.wrap');

var log = console.log.bind(console)

var RESTART_FLUSH_DELAY = 3 * 1000

process.exit = wrap(process.exit, function(originalFunction) {
    log('Waiting', RESTART_FLUSH_DELAY, 'for buffers to flush before restarting')
    setTimeout(originalFunction, RESTART_FLUSH_DELAY)
});

process.exit(1);

推荐阅读
wangtao
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有