Extending your own JavaScript error constructor

I tried to extend the properties of the JavaScript error through the extension of the prototype error constructor:

<script type="text/javascript"> // extending the Error properties to all the ones available in the various browsers: Error.prototype = { name: null, // (all browsers); the name of the error message: null, // (all browsers); the error message as a string description: null, // (Internet Explorer); description of the error fileName: null, // (Firefox); the name of the file where the error occurred lineNumber: null, // (Firefox); the number of line where the error occurred columnNumber: null, // (Firefox); the number of column where the error occurred number: null, // (Internet Explorer); the error code as a number stack: null // (Firefox, Chrome); detailed information about the location where the error exactly occurred }; function log(error) { var errors = []; for (var prop in error) { errors.push(prop + ': ' + error[prop]); } alert(errors.join('\n')); } </script> 

Then I test the log function:

 <script type="text/javascript> try { var a = b; // b is undefined! } catch(error) { log(error); } </script> 

As a result, the error object shows only some properties (for example, in Firefox fileName , lineNumber and columnNumber ), for example, if it has not been extended.

But the strangest thing is that the for...in loop seems unable to execute all the properties of the error object : an attempt to warn the standard error.message property usually returns a message.

So, the results of my test:

  • The error constructor does not expand through its prototype, as other native constructors:
  • the for...in loop is not capable of executing the properties of the error object.

I'm right?
Is there any interesting evidence / resources you can offer to learn more about this?

+4
source share
1 answer

a. For example, Raynos said: The reason message not installed is that Error is a function that returns a new Error object and does not manipulate this in any way.

B. The way to do this correctly is to return the application result from the constructor, and also set the prototype in the usual complex javascripty method:

 function MyError() { var tmp = Error.apply(this, arguments); tmp.name = this.name = 'MyError' this.stack = tmp.stack this.message = tmp.message return this } var IntermediateInheritor = function() {} IntermediateInheritor.prototype = Error.prototype; MyError.prototype = new IntermediateInheritor() var myError = new MyError("message"); console.log("The message is: '"+myError.message+"'") // The message is: 'message' console.log(myError instanceof Error) // true console.log(myError instanceof MyError) // true console.log(myError.toString()) // MyError: message console.log(myError.stack) // MyError: message \n // <stack trace ...> 

The only problems with this way of doing this at this point (I repeated this a bit):

  • properties other than stack and message are not included in MyError and
  • stacktrace has an extra line that is not really needed.

The first problem can be fixed by repeating all of the non-enumerable properties of the error with the trick in this answer: Is it possible to get non-enumerable inherited property names of an object? , but this is not supported, for example, <9. The second problem can be solved by breaking this line in the stack trace, but I'm not sure how to do it safely (maybe just deleting the second line e.stack.toString () ??) .

0
source

All Articles