Using `instanceof` on objects created with constructors from deep npm dependencies

后端 未结 2 498
傲寒
傲寒 2021-02-19 00:48

Background:

I have an npm module that I have common error handling code in, including a custom error:

function CustomError () { /* ... */ }
CustomError         


        
2条回答
  •  名媛妹妹
    2021-02-19 01:39

    This is actually a problem in browsers too, when you have an iframe it gets its own copy of, for example, the Array constructor (making instanceof useless).

    The solution for a custom constructor is to duck-type it. Here are some potential solutions with pros and cons.

    1. Check the constructor name. Pro: simple, well-supported. Con: better pick a fairly unique name to avoid false positives and forget about sub-classing it.

    2. Check the properties of the object (e.g. has both 'foo' and 'bar and 'foo' is a function). Pro: mostly fool-proof. Cons: fragile: this check may randomly break if you refactor your custom error class, relatively expensive.

    3. (Recommended) Add a property/method. This is how a number of libraries (for example, moment.js) handle this problem.

    Code example:

    CustomError.prototype._isCustomError = true;
    var isCustomError = function isCustomError(obj) {
      return obj instanceof CustomError || Boolean(obj._isCustomError);
    };
    
    module.exports = {
      CustomError,
      isCustomError
    };
    

    This is more or less exactly how moment detects whether or not a given object is a moment object.

提交回复
热议问题