2011-12-23 13 views
8

Bir şey başarısız olursa kurucunun nesne yapısını iptal etmesini sağlamaya çalışıyorum, örneğin bir tuval tutmuyor.Javascript'te yeni ile adlandırılan bir kurucudan null nasıl döndürülür?

Ancak, new kullanırken, herhangi bir geri dönüş veya başka bir değerden bağımsız olarak, klass() öğesinin her zaman this değerini döndürdüğünü görüyorum, bunun için boş dönebilir miyim?

Şimdi düşünüyorum, yeni örneği klass() içinde oluşturmak ve bu örneği veya boş değeri döndürmek ve new kullanmamak bir çözüm olabilir, daha iyi bir çözüm var mı?

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

Bir istisna atabilir veya test edilebilecek nesneyi ayarlayabilirsiniz. – jfriend00

cevap

12

yerine "fabrika fonksiyonu" veya "statik fabrika yöntemi" sağlayabilecekleri John Resig's article'da açıklanan tekniği kullanarak tek bir işlevde kurucu. Örnek:

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

Bu konuda bazı değişikliklerin genel olarak daha iyi bir yaklaşım olacağını düşünüyorum. Öğeyi bir işlevde yakalamaya çalışın ve varsa, yapıcıya iletin. Değilse, null döndürün. –

10

daha iyi bir çözüm hata atmak olacaktır:

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 
} 

DÜZENLEME:

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? ;-) 

: Yapıcılar bir örneğini dönmek değil "zorla" olabilir Garip bir şey, ancak, bir "kurucu" bir sayı döndürürse, dize, true, false, vb. Aslında bir örneğini döndürür döndürür. İkinci çözüm, yalnızca kurucu boş bir dizi [] veya boş bir nesne {} döndürdüğünde çalışır.

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

Sadece bir elemanın w olup olmadığını test etmek için kodunuzu "try/catch" ifadeleriyle karıştırmak ister misiniz? bulunduğu gibi? –

+1

Bir eleman bulunup bulunmadığını kontrol etmem. Ancak bir kanvasın gerçekten desteklenip desteklenmediğini doğrulamaya çalışıyorsanız, bir istisna oluşturmayı tercih ederim. –

+0

Evet, güzel. @amnotiam'ın dediği gibi, “eğer (! (A = new klass ('id'))' – Petruza

2

Sen ile bir fabrika birleştirmek kullanabilirsiniz: yeni sınıf sözdizimi kullanılarak

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(); 

Aynı şey:

+0

+1 sadece kopyalamakla kalmayıp aynı zamanda borç vermeniz için. (Ve muhtemelen en iyi sonuç veren tek liner, henüz.) –

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'); 
İlgili konular