使用eval在javascript中导入名称空间
我试图在javascript中将一个名称空间的内容转储到另一个名称空间中。我能想到的唯一直接做到这一点的方法如下:使用eval在javascript中导入名称空间,javascript,Javascript,我试图在javascript中将一个名称空间的内容转储到另一个名称空间中。我能想到的唯一直接做到这一点的方法如下: var CHESSMEN = { Chariot: function(color) { return { color: color, abbreviation: 'R', type: 'Chariot' }; }, Horse: function(color) { return { color:
var CHESSMEN = {
Chariot: function(color) {
return {
color: color,
abbreviation: 'R',
type: 'Chariot'
};
},
Horse: function(color) {
return {
color: color,
abbreviation: 'H',
type: 'Horse'
};
},
Elephant: function(color) {
return {
color: color,
abbreviation: 'E',
type: 'Elephant'
};
},
Advisor: function(color) {
return {
color: color,
abbreviation: 'A',
type: 'Advisor'
};
},
General: function(color) {
return {
color: color,
abbreviation: 'G',
type: 'General'
};
},
Cannon: function(color) {
return {
color: color,
abbreviation: 'C',
type: 'Cannon'
};
},
Soldier: function(color) {
return {
color: color,
abbreviation: 'S',
type: 'Soldier'
};
}
}
Object.freeze(CHESSMEN)
function Game(board) {
for (var piece in CHESSMEN) {
eval('var ' + piece + ' = CHESSMEN.' + piece);
}
if (typeof(board) === 'undefined') {
var board = {
a1: new Chariot('red'),
b1: new Horse('red'),
c1: new Elephant('red'),
d1: new Advisor('red'),
e1: new General('red'),
f1: new Advisor('red'),
g1: new Elephant('red'),
h1: new Horse('red'),
i1: new Chariot('red'),
b3: new Cannon('red'),
h3: new Cannon('red'),
a4: new Soldier('red'),
c4: new Soldier('red'),
e4: new Soldier('red'),
g4: new Soldier('red'),
i4: new Soldier('red'),
a10: new Chariot('black'),
b10: new Horse('black'),
c10: new Elephant('black'),
d10: new Advisor('black'),
e10: new General('black'),
f10: new Advisor('black'),
g10: new Elephant('black'),
h10: new Horse('black'),
i10: new Chariot('black'),
b8: new Cannon('black'),
h8: new Cannon('black'),
a7: new Soldier('black'),
c7: new Soldier('black'),
e7: new Soldier('black'),
g7: new Soldier('black'),
i7: new Soldier('black')
};
}
// et cetera
}
在这里,我使用
for in
循环来迭代冻结对象的键,并使用eval
将这些键及其相关值转储到游戏
构造函数的范围内。许多人告诉我不要使用eval
,但我没有看到其他直接合并名称空间的方法。这不安全吗?对我来说,调用棋子构造函数作为棋子
对象的属性会更好吗?正如@zerkms所指出的,您应该使用棋子.战车
等来访问它们:
var board = {
a1: new CHESSMAN.Chariot('red'),
b1: new CHESSMAN.Horse('red'),
c1: new CHESSMAN.Elephant('red'),
//etc.
此外,如果您要使用新,您几乎肯定不希望您的战车以您现有的方式实现。您想要的模式是:
Chariot: function(color) {
this.color = color;
this.abbreviation = 'R';
this.type = 'Chariot'
},
否则,当您调用new
时,将返回您正在创建的对象文本,而不是您可能想要的Chariot
实例。如果您真正需要的只是返回的值,那么您可以编写代码而无需new
:
var board = {
a1: CHESSMAN.Chariot('red'),
b1: CHESSMAN.Horse('red'),
c1: CHESSMAN.Elephant('red'),
//etc.
这是可能的,但在严格的模式下,这是不可能的
with (CHESSMEN) {
// Now CHESSMEN's properties are available without saying "CHESSMEN.whatever"
console.log(Chariot === CHESSMEN.Chariot); // logs "true"
}
我重申:这是一个坏主意。很难判断任何标识符所指的是什么,它可能运行得较慢,并且不具有前向兼容性。有关更多详细信息,请参阅
至于评估的安全性:如果在以后某个时候,您的代码发生了变化,使得棋子
可以具有用户定义的属性,攻击者可以将属性命名为foo;dohorblyevillthing()代码>导致您的代码做了可怕的坏事。为什么需要导入它们?为什么不直接用作棋子、战车等呢?我想知道导入它们是否有任何不利之处。但是为了回答你的问题,我没有充分的理由使用战车而不是棋子。战车。我只是好奇这个公式是否不安全。是的,有-你在做一些解决任务不需要的事情。你的每一步都应该有一些要求。相反,当你做了一些奇怪的事情并用“为什么不”来解释它们时,这不是真的。顺便说一句,这个问题与“安全性”无关。或者应该澄清“安全”术语的用法。关于@zerkms标签,您可能是对的。关于我的名字空间。谢谢你的建议,谢谢。我想我将不得不习惯在javascript中保持单独的名称空间。我特别欣赏您的观点,即即使当前没有安全问题,我也必须在将来修改代码时始终担心安全问题。@handyandshortstack:what的安全性?你在保护自己吗?