2011-12-23 11 views
8

यदि कुछ विफल रहता है तो मैं कन्स्ट्रक्टर ऑब्जेक्ट निर्माण को निरस्त करने की कोशिश कर रहा हूं, उदाहरण के लिए यह कैनवास को पकड़ नहीं सकता है।जावास्क्रिप्ट में नए के साथ बुलाए गए कन्स्ट्रक्टर से नल कैसे वापस करें?

लेकिन जैसा कि मैं new का उपयोग कर रहा हूं, मुझे लगता है कि klass() हमेशा this लौटाता है, चाहे कोई वापसी नल या कोई अन्य मूल्य चाहे, क्या मैं इसे वापस शून्य करने के लिए काम कर सकता हूं?

अब मुझे लगता है कि एक समाधान क्लास() के अंदर नया उदाहरण बनाने के लिए हो सकता है और उस उदाहरण या शून्य को वापस कर सकता है, और new का उपयोग नहीं करता है, क्या कोई बेहतर समाधान है?

function klass(canvas_id) { 
    var canvas = document.getElementById(canvas_id); 

    if(! (canvas && canvas.getContext)) { 
     return null; 
    } 
} 
var instance = new klass('wrong_id'); 
console.log(instance, typeof instance); 
+1

आप एक अपवाद फेंक सकते हैं या आप अपने ऑब्जेक्ट में कुछ राज्य सेट कर सकते हैं जिसका परीक्षण किया जा सकता है। – jfriend00

उत्तर

12

आप एक "कारखाने समारोह" या "स्थिर कारखाने विधि" के बजाय कर सकता है John Resig's article में वर्णित तकनीक का उपयोग करके एक समारोह में कन्स्ट्रक्टर। उदाहरण:

function Person(name) { 
    var me = arguments.callee; 

    if (!(this instanceof me)) { 
     // factory code 

     // validate parameters.... 
     if(!name.match(/^[a-z]+$/)) 
      return null; 

     // ...and call the constructor 
     return new me(arguments); 

    } else { 

     // constructor code 
     this.name = name;  

    } 
} 


a = Person("joe") // ok 
b = Person("bob") // ok 
c = Person("R2D2") // null 
+0

मुझे लगता है कि इस पर कुछ बदलाव आम तौर पर बेहतर दृष्टिकोण होगा। किसी फ़ंक्शन में तत्व को पकड़ने का प्रयास करें, और यदि कोई पाया जाता है, तो इसे कन्स्ट्रक्टर पर पास करें। यदि नहीं, तो शून्य वापस आओ। –

10

बेहतर समाधान एक त्रुटि फेंक होगा:

function klass(canvas_id) { 
    var canvas = document.getElementById(canvas_id); 

    if(! (canvas && canvas.getContext)) { 
     throw new Error('Not a canvas'); 
    } 
} 

// later... 

try { 
    var c = new klass("canvas_id"); 
} catch(E) { 
    // error caught 
} 

संपादित करें: कंस्ट्रक्टर्स कर सकते हैं "मजबूर" किया एक उदाहरण वापस नहीं करने के लिए:

function Foo() { 
    var canvas = ...; 

    if ('undefined' == '' + Foo.CANVAS_CHECK) 
     Foo.CANVAS_CHECK = (canvas && canvas.getContext); 

    if (!Foo.CANVAS_CHECK) 
     return []; // the constructor will actually return an empty array 

    // passed; initialize instance here 
} 


// later on... 

var foo; 

if (!((foo = new Foo()) instanceof Foo)) { 
    // Failed. Canvas is unsupported. 
} 

// You happy now, am not i am? ;-) 

हालांकि, अजीब चीज यह है कि यदि एक "कन्स्ट्रक्टर" एक संख्या देता है, स्ट्रिंग, true, false, आदि, यह वास्तव में एक उदाहरण देता है। दूसरा समाधान केवल तभी काम करता है जब कन्स्ट्रक्टर रिक्त सरणी [] या खाली ऑब्जेक्ट {} देता है।

Foo.CreateFoo = function() { 
    // not to confuse with Foo.prototype. ... 
    if (something) { 
    return null; 
    } 
    return new Foo(); 
}; 

// then instead of new Foo(): 
var obj = Foo.CreateFoo(); 

यही बात नए वर्ग सिंटैक्स का उपयोग:

class Foo { 
    static CreateFoo() { 
    if (something) { 
     return null; 
    } 
    return new Foo(); 
    } 
} 
+1

क्या आप वाकई 'कोड/कैच' कथन के साथ अपने कोड को अव्यवस्थित करना चाहते हैं, यह जांचने के लिए कि कोई तत्व डब्ल्यू जैसा पाया गया है? –

+1

यह जांचने के लिए कि कोई तत्व नहीं मिला है। लेकिन अगर आप सत्यापित करने की कोशिश कर रहे हैं कि कैनवास वास्तव में समर्थित है, तो मैं अपवाद उठाऊंगा। –

+0

हाँ, यह अच्छा है। यद्यपि @amnotiam कहता है, मैं बेहतर एक सिंगल लाइनर जैसे 'if (! (A = new klass (' id '))' – Petruza

2

आप के साथ एक कारखाना गठबंधन का उपयोग कर सकते

+0

+1 सिर्फ कॉपी करने के लिए नहीं बल्कि क्रेडिट दे रहा है जहां यह देय है। (और शायद सबसे अच्छा परिणामस्वरूप एक-लाइनर, अभी तक।) –

0

जैसा कि मैंने ऊपर मेरी टिप्पणी में तैनात ...

function klass(canvas_id) { 
    var canvas = document.getElementById(canvas_id); 

    if(! (canvas && canvas.getContext)) { 
     return new Boolean; 
    } 
} 

var instance1 = new klass('wrong_id'); 

if(!(instance1 instanceof klass)) 
    console.log('Canvas is not suppored'); 

var instance2 = new klass('wrong_id').valueOf(); 

console.log(instance2, typeof instance2); 

if(instance2 !== false) 
    console.log('Canvas is supported, yeah');