2011-08-23 100 views
7

JavaScript的新手在這裏,我要通過在工作中的一些js代碼,當我遇到對象創建一個輔助功能,它是這樣進行的JavaScript對象創建

createElement = function(name, data){ 
    if(name == TYPES.TEXT){ 
    return new Text(data); 
    } 
    else if(name == TYPES.WORD){ 
    return new Word(data); 
    } 
    else if(name == TYPES.PARAGRAPH){ 
    return new Paragraph(data); 
    } 
    else if(name == TYPES.TABLE){ 
    return new Table(data); 
    } 
    <list goes on and on and on... > 
} 

,而這並完成這項工作我會來到想知道是否有更好,更清潔的寫作方式。

+0

你可能會感興趣的[開關結構(https://developer.mozilla.org/en/JavaScript/Reference/Statements/switch)... – DaveRandom

回答

9

你是對的,過多if..thenswitch邏輯是code smell,幾乎總是可以重構成更優雅的東西。在這種情況下,基於名稱的工廠可重構與鍵作爲名稱和值作爲函數的字典返回

var dictionary = {}; 
dictionary[TYPES.TEXT] = Text; 
dictionary[TYPES.WORD] = Word; 
dictionary[TYPES.PARAGRAPH] = Paragraph; 
dictionary[TYPES.TABLE] = Table; 

createElement = function(name, data){ 
    return new dictionary[name](data); 
} 

活生生的例子:http://jsfiddle.net/KkMnd/

編輯:這行createElement方法可以/應該首先檢查是否爲傳入的TYPES.*配置了一些內容。一種好方法是在嘗試調用該方法之前檢查字典中是否存在元素。

return (typeof dictionary[name] == 'function') ? new dictionary[name](data) : some_default_value; 
+0

我喜歡他的回答更好。 – Prospero

+0

+1這個解決方案的另外一個好處是,如果你的'TYPES'需要擴展,你不需要改變任何*邏輯*來做到這一點,你必須做一個'switch'。 – peirix

+3

+1用於簡化和提及此模式的名稱(工廠模式)。我擔心的是OP沒有提到最後的「_else_」聲明,你也應該在這裏實現它,例如。 'return(typeof dictionary [name]!='undefined')? dictionary [name](data):something_goes_here;'(如果沒有發現,只需用預期的結果替換'something_goes_here')。 – Tadeck

0

這將是一個更清潔,但在語義上使用switch語句相同。

function createElement(name,data){ 
switch(name) 
{ 
case TYPES.TEXT: 
    return new Text(data) 
    break; 
case TYPES.WORD: 
    return new WORD(data) 
    break; 
default: 
    // etc. code to be executed if no values match 
} 
}