2010-12-05 18 views
8

Javascript'te değişken bir dize (nesnenin adını içeren) temel alarak yeni bir nesneyi nasıl oluşturabilirim?Javascript'te tip-dizgeye dayalı olarak yeni bir nesneyi nasıl oluşturabilirim?

function getTool(name){ 
    switch(name){ 
    case "SelectTool": 
     return new SelectTool(); 
     break; 
    case "LineTool": 
     return new LineTool(); 
     break; 
    case "BlurTool": 
     return new BlurTool(); 
     break; 
    case "PointerTool": 
    default: 
     return new PointerTool(); 
     break; 
    } 
} 

(... uzun alacak listesi geliyor daha araçlarıyla) Ve benzeri Aletlerimi tanımlamıştır:: Artık

Ben

PointerTool.prototype = new Tool; 
PointerTool.prototype.constructor = PointerTool; 
function PointerTool(){ 
    this.name = "PointerTool"; 
} 
PointerTool.prototype.click = function(x, y){ 
    info("You clicked at: "+x+", "+y); 
} 

Ben binmek almak istiyorum (büyüyen) anahtar deyimi, 'yanlış' gibi görünüyor.

+0

Varsayımsal olarak, bunu yapabilirdi ... –

+2

@ Šime Vidas, ama pratik olarak, tüm maliyetlerden kaçınılmalıdır: D –

+0

@Gabi, 'eval() 'ın burada doğru çözüm olmadığını kabul ediyorum, ama ben “Neden her ne pahasına olursa olsun kaçınılmalıdır” diye sorduğunuzu merak ediyorsunuz. Diğer tüm özellikler gibi, uygun (ve uygun olmayan) kullanımlarla dilin kullanım dışı bir özelliği. – Lee

cevap

17
function getTool(name){ 
    return (typeof window[name] === 'function') ? 
            new window[name]() : {/*some default*/}; 
} 

PointerTool yapıcı küresel window ad alanında tanımlanır varsayar. Bunu, kullandığınız ad alanı ile değiştirin.

+1

Eğer Node.js kullanıyorsanız, aynı şeyi yapmak için GLOBAL nesnesini kullanabilirsiniz. –

+0

Şimdilik bu çözüm ile gideceğim, tamamen _everything_ bir fonksiyon olduğunu unutmuş, bu yüzden de küresel 'window' nesne/fonksiyon/namespace :) – Dribbel

+0

@Dribbel - Sesler iyi. Sadece pencereyi kullandım çünkü isim alanından emin değildim. 'Window' kullanıyorsanız, bunları başka bir ad alanında tanımlamanızı öneririm. Aynı teknik kullanılabilir, ancak "getTool" başka bir şey yapmıyorsa, bu işlev çağrısını ortadan kaldırabilirsiniz. – user113716

8

Yaklaşımınızı yeniden düşünmeyi düşünmelisiniz. Hem new Tools.SelectTool ve new Tools[var_with_tool_name] gibi araçları erişebilir,

Tools = {"SelectTool": SelectTool /* etc */}`. 

gibi, bu şekilde özellikleri gibi araçlara sahip olacak bir Tools nesne gibi bir şey olması daha iyi olurdu.

+0

Bu bana Patrick'in yaklaşımından daha karmaşık görünüyor. –

+2

Evet, ancak araçlar farklı ad alanlarında olsa bile çalışır. –

3

Örneğinizde, global kapsamda bir işlev olarak PointerTool bildiriyorsunuz. Javascript'in tarayıcıyı çalıştırdığını varsayarsak, "global kapsam" aslındawindow nesnesi ile aynıdır.

function PointerTool() { 
    ... 
} 

bu aynıdır: sizin getTool işlevinde, Şimdi

window.PointerTool = function() { 
    ... 
} 

, bu gibi yapıcı fonksiyonları erişebilirsiniz: O bir kurucu varsa demektir

function getTool(name){ 
    return new window[name](); 
} 

Bunu yapmanın daha "gelecekteki kanıtı" yolu, içine yerleştireceğiniz kendi ad alanı nesnesini tanımlamaktır. tüm çeşitli aracı kurucuları. Böyle bir şey ("myproject" Projenizin veya sistem kısa adı olacaktır):

var myproject = { tools: {} }; 

// Pointer Tool Constructor 
myproject.tools.PointerTool = function() { 
    ... 
} 

// Line Tool Constructor 
myproject.tools.LineTool = function() { 
    ... 
} 

// and so on 

Sonra getTool fonksiyonu şu şekilde görünecektir:

function getTool(name){ 
    return new myproject.tools[name](); 
} 

Bu yaklaşım izole eşyalarını tutar ne olursa olsun Diğer şeyler global/window kapsamında tanımlanır.

+0

Hayır, 'işlev PointerTool' ≠' window.PointerTool = function': birincisi bir işlevdir * declaration *, ikincisi bir işlev * expression *. http://kangax.github.com/nfe/#expr-vs-decl –

+0

Doğru, ama bu soru bağlamında, bu yeterince eşittir. Yani, bu cevabın noktası olan 'window.PointerTool' kullanarak' PointerTool''na başvurabilirsiniz. – MooGoo

İlgili konular