क्या मैं जावास्क्रिप्ट में उपयोगकर्ता-परिभाषित अपवादों के लिए एक कस्टम प्रकार परिभाषित कर सकता हूं? यदि हां, तो मैं इसे कैसे करूंगा?
क्या मैं जावास्क्रिप्ट में उपयोगकर्ता-परिभाषित अपवादों के लिए एक कस्टम प्रकार परिभाषित कर सकता हूं? यदि हां, तो मैं इसे कैसे करूंगा?
जवाबों:
से WebReference :
throw {
name: "System Error",
level: "Show Stopper",
message: "Error detected. Please contact the system administrator.",
htmlMessage: "Error detected. Please contact the <a href=\"mailto:sysadmin@acme-widgets.com\">system administrator</a>.",
toString: function(){return this.name + ": " + this.message;}
};
catch (e) { if (e instanceof TypeError) { … } else { throw e; } }
something या something catch (e) { switch (e.constructor) { case TypeError: …; break; default: throw e; }
something की तरह है।
आपको एक कस्टम अपवाद बनाना चाहिए जो प्रोटोटाइप त्रुटि से विरासत में मिला है। उदाहरण के लिए:
function InvalidArgumentException(message) {
this.message = message;
// Use V8's native method if available, otherwise fallback
if ("captureStackTrace" in Error)
Error.captureStackTrace(this, InvalidArgumentException);
else
this.stack = (new Error()).stack;
}
InvalidArgumentException.prototype = Object.create(Error.prototype);
InvalidArgumentException.prototype.name = "InvalidArgumentException";
InvalidArgumentException.prototype.constructor = InvalidArgumentException;
यह मूल रूप से फ़ायरफ़ॉक्स और अन्य ब्राउज़रों पर स्टैक के निशान को बढ़ाने वाली वृद्धि के साथ ऊपर पोस्ट किए गए विघटित का एक सरलीकृत संस्करण है। यह उन्हीं परीक्षणों को संतुष्ट करता है जो उन्होंने पोस्ट किए थे:
उपयोग:
throw new InvalidArgumentException();
var err = new InvalidArgumentException("Not yet...");
और यह व्यवहार किया जाएगा उम्मीद है:
err instanceof InvalidArgumentException // -> true
err instanceof Error // -> true
InvalidArgumentException.prototype.isPrototypeOf(err) // -> true
Error.prototype.isPrototypeOf(err) // -> true
err.constructor.name // -> InvalidArgumentException
err.name // -> InvalidArgumentException
err.message // -> Not yet...
err.toString() // -> InvalidArgumentException: Not yet...
err.stack // -> works fine!
आप अपने स्वयं के अपवादों और उनकी हैंडलिंग को यहां उदाहरण के लिए लागू कर सकते हैं:
// define exceptions "classes"
function NotNumberException() {}
function NotPositiveNumberException() {}
// try some code
try {
// some function/code that can throw
if (isNaN(value))
throw new NotNumberException();
else
if (value < 0)
throw new NotPositiveNumberException();
}
catch (e) {
if (e instanceof NotNumberException) {
alert("not a number");
}
else
if (e instanceof NotPositiveNumberException) {
alert("not a positive number");
}
}
टाइप किए गए अपवाद को पकड़ने के लिए एक और वाक्यविन्यास है, हालांकि यह हर ब्राउज़र में काम नहीं करेगा (उदाहरण के लिए IE में नहीं):
// define exceptions "classes"
function NotNumberException() {}
function NotPositiveNumberException() {}
// try some code
try {
// some function/code that can throw
if (isNaN(value))
throw new NotNumberException();
else
if (value < 0)
throw new NotPositiveNumberException();
}
catch (e if e instanceof NotNumberException) {
alert("not a number");
}
catch (e if e instanceof NotPositiveNumberException) {
alert("not a positive number");
}
हाँ। आप जो कुछ भी चाहते हैं उसे फेंक सकते हैं: पूर्णांक, तार, ऑब्जेक्ट, जो भी हो। यदि आप किसी वस्तु को फेंकना चाहते हैं, तो बस एक नई वस्तु बनाएं, जैसे आप अन्य परिस्थितियों में एक बनाएंगे, और फिर उसे फेंक देंगे। मोज़िला के जावास्क्रिप्ट संदर्भ के कई उदाहरण हैं।
function MyError(message) {
this.message = message;
}
MyError.prototype = new Error;
यह जैसे उपयोग के लिए अनुमति देता है ..
try {
something();
} catch(e) {
if(e instanceof MyError)
doSomethingElse();
else if(e instanceof Error)
andNowForSomethingCompletelyDifferent();
}
e instanceof Error
झूठ होगा।
e instanceof MyError
यह सच होगा, else if(e instanceof Error)
बयान का मूल्यांकन कभी नहीं किया जाएगा।
else if(e instanceof Error)
आखिरी कैच कहां होगा। इसके बाद एक सरल else
(जिसका मैंने समावेश नहीं किया)। तरह का क्रमबद्ध default:
एक स्विच बयान में लेकिन त्रुटियों के लिए।
संक्षेप में:
यदि आप ट्रांसपॉयर्स के बिना ES6 का उपयोग कर रहे हैं :
class CustomError extends Error { /* ... */}
वर्तमान सर्वोत्तम अभ्यास के लिए ES6 सिंटैक्स के साथ जावास्क्रिप्ट में फैली हुई त्रुटि देखें
यदि आप बैबल ट्रांसपिलर का उपयोग कर रहे हैं :
विकल्प 1: बेबल-प्लगइन-ट्रांसफॉर्मेशन-बिलिन-एक्सटेंशन का उपयोग करें
विकल्प 2: इसे स्वयं करें (उसी पुस्तकालय से प्रेरित)
function CustomError(...args) {
const instance = Reflect.construct(Error, args);
Reflect.setPrototypeOf(instance, Reflect.getPrototypeOf(this));
return instance;
}
CustomError.prototype = Object.create(Error.prototype, {
constructor: {
value: Error,
enumerable: false,
writable: true,
configurable: true
}
});
Reflect.setPrototypeOf(CustomError, Error);
यदि आप शुद्ध ES5 का उपयोग कर रहे हैं :
function CustomError(message, fileName, lineNumber) {
const instance = new Error(message, fileName, lineNumber);
Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
return instance;
}
CustomError.prototype = Object.create(Error.prototype, {
constructor: {
value: Error,
enumerable: false,
writable: true,
configurable: true
}
});
if (Object.setPrototypeOf){
Object.setPrototypeOf(CustomError, Error);
} else {
CustomError.__proto__ = Error;
}
वैकल्पिक: Classtrophobic ढांचे का उपयोग करें
स्पष्टीकरण:
ES6 और बैबल का उपयोग करके त्रुटि वर्ग का विस्तार क्यों एक समस्या है?
क्योंकि CustomError की एक उदाहरण अब इस तरह से मान्यता प्राप्त नहीं है।
class CustomError extends Error {}
console.log(new CustomError('test') instanceof Error);// true
console.log(new CustomError('test') instanceof CustomError);// false
वास्तव में, कोलाहल के आधिकारिक दस्तावेज से, आप किसी भी अंतर्निहित जावास्क्रिप्ट वर्गों विस्तार नहीं कर सकते जैसे Date
, Array
, DOM
या Error
।
समस्या यहाँ वर्णित है:
अन्य SO उत्तर के बारे में क्या?
दिए गए सभी उत्तर समस्या को ठीक करते हैं instanceof
लेकिन आप नियमित त्रुटि खो देते हैं console.log
:
console.log(new CustomError('test'));
// output:
// CustomError {name: "MyError", message: "test", stack: "Error↵ at CustomError (<anonymous>:4:19)↵ at <anonymous>:1:5"}
जबकि ऊपर उल्लिखित विधि का उपयोग करके, न केवल आप समस्या को ठीक करते हैं, instanceof
बल्कि आप नियमित त्रुटि भी रखते हैं console.log
:
console.log(new CustomError('test'));
// output:
// Error: test
// at CustomError (<anonymous>:2:32)
// at <anonymous>:1:5
यहां बताया गया है कि आप मूल Error
व्यवहार के साथ पूरी तरह से कस्टम त्रुटि कैसे बना सकते हैं । यह तकनीक अभी के लिए केवल क्रोम और नोड.जेएस में काम करती है । अगर आप यह नहीं समझते हैं कि मैं इसका इस्तेमाल करने की सलाह नहीं दूंगा।
Error.createCustromConstructor = (function() {
function define(obj, prop, value) {
Object.defineProperty(obj, prop, {
value: value,
configurable: true,
enumerable: false,
writable: true
});
}
return function(name, init, proto) {
var CustomError;
proto = proto || {};
function build(message) {
var self = this instanceof CustomError
? this
: Object.create(CustomError.prototype);
Error.apply(self, arguments);
Error.captureStackTrace(self, CustomError);
if (message != undefined) {
define(self, 'message', String(message));
}
define(self, 'arguments', undefined);
define(self, 'type', undefined);
if (typeof init == 'function') {
init.apply(self, arguments);
}
return self;
}
eval('CustomError = function ' + name + '() {' +
'return build.apply(this, arguments); }');
CustomError.prototype = Object.create(Error.prototype);
define(CustomError.prototype, 'constructor', CustomError);
for (var key in proto) {
define(CustomError.prototype, key, proto[key]);
}
Object.defineProperty(CustomError.prototype, 'name', { value: name });
return CustomError;
}
})();
एक रिआल्ट के रूप में हमें मिलता है
/**
* name The name of the constructor name
* init User-defined initialization function
* proto It's enumerable members will be added to
* prototype of created constructor
**/
Error.createCustromConstructor = function(name, init, proto)
तो आप इसे इस तरह से उपयोग कर सकते हैं:
var NotImplementedError = Error.createCustromConstructor('NotImplementedError');
और NotImplementedError
जैसा कि आप उपयोग करेंगे Error
:
throw new NotImplementedError();
var err = new NotImplementedError();
var err = NotImplementedError('Not yet...');
और यह व्यवहार किया जाएगा उम्मीद है:
err instanceof NotImplementedError // -> true
err instanceof Error // -> true
NotImplementedError.prototype.isPrototypeOf(err) // -> true
Error.prototype.isPrototypeOf(err) // -> true
err.constructor.name // -> NotImplementedError
err.name // -> NotImplementedError
err.message // -> Not yet...
err.toString() // -> NotImplementedError: Not yet...
err.stack // -> works fine!
ध्यान दें, कि error.stack
निरपेक्ष सही काम करता है और इसमें NotImplementedError
कंस्ट्रक्टर कॉल (v8 के लिए धन्यवाद Error.captureStackTrace()
) शामिल नहीं होगा ।
ध्यान दें। बदसूरत है eval()
। इसका उपयोग करने का एकमात्र कारण सही होना है err.constructor.name
। यदि आपको इसकी आवश्यकता नहीं है, तो आप सब कुछ सरल कर सकते हैं।
Error.apply(self, arguments)
है काम करने के लिए नहीं निर्दिष्ट । मेरा सुझाव है कि स्टैक ट्रेस को कॉपी करना है जो क्रॉस-ब्राउज़र संगत है।
मैं अक्सर प्रोटोटाइप विरासत के साथ एक दृष्टिकोण का उपयोग करता हूं। ओवरराइड करने toString()
से आपको यह फायदा होता है कि फायरबग जैसे उपकरण [object Object]
बिना किसी अपवाद के कंसोल के बजाय वास्तविक जानकारी को लॉग इन करेंगे ।
instanceof
अपवाद के प्रकार को निर्धारित करने के लिए उपयोग करें ।
// just an exemplary namespace
var ns = ns || {};
// include JavaScript of the following
// source files here (e.g. by concatenation)
var someId = 42;
throw new ns.DuplicateIdException('Another item with ID ' +
someId + ' has been created');
// Firebug console:
// uncaught exception: [Duplicate ID] Another item with ID 42 has been created
ns.Exception = function() {
}
/**
* Form a string of relevant information.
*
* When providing this method, tools like Firebug show the returned
* string instead of [object Object] for uncaught exceptions.
*
* @return {String} information about the exception
*/
ns.Exception.prototype.toString = function() {
var name = this.name || 'unknown';
var message = this.message || 'no description';
return '[' + name + '] ' + message;
};
ns.DuplicateIdException = function(message) {
this.name = 'Duplicate ID';
this.message = message;
};
ns.DuplicateIdException.prototype = new ns.Exception();
फेंक कथन का उपयोग करें ।
जावास्क्रिप्ट परवाह नहीं करता है कि अपवाद प्रकार क्या है (जैसा कि जावा करता है)। जावास्क्रिप्ट सिर्फ नोटिस, एक अपवाद है और जब आप इसे पकड़ते हैं, तो आप "अपवाद" कहते हैं "देख सकते हैं"।
यदि आपके पास अलग-अलग अपवाद प्रकार हैं जिन्हें आपको फेंकना है, तो मैं उन चर का उपयोग करने का सुझाव दूंगा जिनमें अपवाद / संदेश का स्ट्रिंग / ऑब्जेक्ट शामिल है। जहां आपको इसकी आवश्यकता है "थ्रो माय एक्ससेप्शन" का उपयोग करें और कैच में, कैप्शन को माई एक्ससेप्शन से तुलना करें।
एमडीएन में इस उदाहरण को देखें ।
यदि आपको कई त्रुटियों को परिभाषित करने की आवश्यकता है ( यहां कोड का परीक्षण करें !):
function createErrorType(name, initFunction) {
function E(message) {
this.message = message;
if (Error.captureStackTrace)
Error.captureStackTrace(this, this.constructor);
else
this.stack = (new Error()).stack;
initFunction && initFunction.apply(this, arguments);
}
E.prototype = Object.create(Error.prototype);
E.prototype.name = name;
E.prototype.constructor = E;
return E;
}
var InvalidStateError = createErrorType(
'InvalidStateError',
function (invalidState, acceptedStates) {
this.message = 'The state ' + invalidState + ' is invalid. Expected ' + acceptedStates + '.';
});
var error = new InvalidStateError('foo', 'bar or baz');
function assert(condition) { if (!condition) throw new Error(); }
assert(error.message);
assert(error instanceof InvalidStateError);
assert(error instanceof Error);
assert(error.name == 'InvalidStateError');
assert(error.stack);
error.message;
कोड ज्यादातर से कॉपी किया जाता है: जावास्क्रिप्ट में त्रुटि को बढ़ाने का एक अच्छा तरीका क्या है?
ES2015 वर्गों के साथ उपयोग के लिए एसेलिन के उत्तर का एक विकल्प
class InvalidArgumentException extends Error {
constructor(message) {
super();
Error.captureStackTrace(this, this.constructor);
this.name = "InvalidArgumentException";
this.message = message;
}
}
//create error object
var error = new Object();
error.reason="some reason!";
//business function
function exception(){
try{
throw error;
}catch(err){
err.reason;
}
}
अब हम कारण या जो भी गुण चाहते हैं, उसे त्रुटि ऑब्जेक्ट में जोड़ते हैं और इसे पुनः प्राप्त करते हैं। त्रुटि को और अधिक उचित बनाकर।