【问题标题】:Wrap all methods of existing javascript object with try catch用 try catch 包装现有 javascript 对象的所有方法
【发布时间】:2016-03-24 15:00:34
【问题描述】:

是否有一种下降方式可以使用 try catch 将所有方法包装在现有的 javascript 对象(例如第三方库)中,以便我可以处理异常错误?当然,我将在新接口下公开这些方法。

这是我现在想到的:(将其视为伪代码)

var MyInterface = {};
for (var property in thirdPartyLib) {
  if ((typeof thirdPartyLib[property]) === 'function'){
    MyInterfac[property] = function(){
      try {
        thirdPartyLib[property](arguments)
      }
      catch(err){
         //do my custom processing
      }
    }
  }   
}

//developer use MyInterface object

只是想知道,我的上述想法有什么更好的方法或任何缺陷吗?谢谢。

【问题讨论】:

  • (typeof thirdPartyLib[property]) 不需要用括号括起来。

标签: javascript error-handling


【解决方案1】:

几乎!唯一的问题是您没有正确传递参数。 arguments 是一个伪数组对象,其中包含 所有 传递给函数调用的参数。你的代码最终会发生什么,真正的函数将被一个对象调用,而不是你在包装函数中收到的单个参数。

您还可以使用闭包进行就地包装,因此您无需担心使用不同的对象。

function safeWrap(service, fn) {
    var ogFn = service[fn];
    service[fn] = function () {
       try { return ogFn.apply(service, arguments); }
       catch (err) {
           // doh.
       }
    };  
}

function wrapObj(service) {    
    for (var fn in thirdPartyLib) {
        var type = typeof(thirdPartyLib[fn]);
        if (type === 'function') {
            safeWrap(thirdPartyLib, fn);
        } else if (type === 'object') {
            wrapObj(thirdPartyLib[fn]);
        }
    }
}

wrapObj(thirdPartyLib);

根据@RobG 的建议进行了编辑以使包装递归

如果性能有问题,您可以手动传递参数以避免使用Function.apply 带来的性能损失:

function safeWrap(service, fn) {
    var ogFn = service[fn];
    service[fn] = function (a, b, c, d, e, f, g, h, i, j, k, l) {
       if (arguments.length > 12) {
           console.error('Time to add %s more args!', arguments.length - 12);
       }
       try { return ogFn.call(service, a, b, c, d, e, f, g, h, i, j, k, l); }
       catch (err) {
           // doh.
       }
    };  
}

【讨论】:

  • 这是一种浅包装。 ;-) 它应该是递归的,因为许多库的方法不止一个对象,例如myLib.dom.getElement()。对此的性能影响有任何估计吗?
  • 哇,好点子!更新以使其递归。我不希望初始设置会产生很大的性能影响,因为它只需要执行一次。这是一个关于 try/catch 性能的问题:stackoverflow.com/questions/19727905/… ... 但看起来主要风险是使用 apply() 与直接函数调用:stackoverflow.com/questions/8184466/…。如果担心最大可能性能,您始终可以手动传递参数。
  • 谢谢!像魅力一样工作!
猜你喜欢
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
  • 1970-01-01
  • 2012-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-24
相关资源
最近更新 更多