2017-09-25 41 views
0

我想在節點中動態創建一個對象。爲此,我使用了這樣的代碼。 在節點服務器中使用eval是一個壞主意嗎?這是在節點服務器中使用eval的一個壞主意嗎?

var a1 = require(./a1.js), 
    a2 = require(./a2.js), 
    ... 
    aN = require(./aN.js); 

    function createObj(pObjName, pObjValue){ 
     var tmp = new eval(pObjName)(pObjValue); 
     //where pObjName is a1 or a1 or .... or aN 
    } 
+2

很難猜測你想達到的目標,但很可能有更好的方法來做到這一點。 –

回答

2

從你展示什麼,有沒有必要使用eval

const Classes = { 
    a1 : require('./a1'), 
    a2 : require('./a2'), 
    ... 
}; 

function createObj(pObjName, pObjValue){ 
    var tmp = new Classes[pObjName](pObjValue); 
    ... 
} 
+1

甚至'new(require('./'+ pObjName))(pObjValue)'就足夠了,因爲已解析的依賴關係會被記憶並且連續調用不會有任何額外開銷。 –

+1

@PatrickRoberts是的,這將是另一個很好的解決方案:)(雖然取決於'pObjName'來自哪裏,它可能需要首先進行消毒) – robertklep

+0

我曾考慮過這種替代方案。既然你也建議我,我會採用這個解決方案。 謝謝 –

0

如果你想保存自己,宣佈所有的時間依賴關係,你甚至可以編寫一個函數,而無需使用eval,處理更有效的情況下:

function createObj(pObjName, pObjValue) { 
    var tmp = new (require('./' + pObjName))(pObjValue); 
    // ... 
} 

請注意,這僅僅是安全的,如果createObj()是保證一個pObjName是你所期望的被調用,否則你需要先驗證它,可能是這樣的:

function createObj(pObjName, pObjValue) { 
    if (!/^a\d$/.test(pObjName)) { 
    throw new TypeError('invalid name') 
    } 

    var tmp = new (require('./' + pObjName))(pObjValue); 
    // ... 
} 
相關問題