如何在 Javascript 中包装函数? [英] How do I wrap a function in Javascript?

查看:27
本文介绍了如何在 Javascript 中包装函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm writing a global error handling "module" for one of my applications.

我想要的功能之一是能够使用 try{} catch{} 块轻松包装函数,以便对该函数的所有调用都将自动进行错误处理将调用我的全局日志记录方法的代码.(为了避免用 try/catch 块到处污染代码).

One of the features I want to have is to be able to easily wrap a function with a try{} catch{} block, so that all calls to that function will automatically have the error handling code that'll call my global logging method. (To avoid polluting the code everywhere with try/catch blocks).

然而,这有点超出我对 JavaScript 的低级功能的理解,.call.apply 方法,以及 this 关键字.

This is, however, slightly beyond my understanding of the low-level functioning of JavaScript, the .call and .apply methods, and the this keyword.

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

I wrote this code, based on Prototype's Function.wrap method:

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,然后调用我的全局错误处理程序.

That code works perfectly. It prints out 6, and then calls my global error handler.

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

My question is: will this break something when the function I'm wrapping is within an object, and it uses the "this" operator? I'm slightly worried since I'm calling .apply, passing something there, I'm afraid this may break something.

推荐答案

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

Personally instead of polluting builtin objects I would go with a decorator technique:

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

但是如果你真的想修改原型,你可以这样写:

But if you do feel like modifying prototypes, you can write it like that:

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 块中调用的函数.

Obvious improvement will be to parameterize makeSafe() so you can specify what function to call in the catch block.

这篇关于如何在 Javascript 中包装函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆