使用eval导入javascript中的命名空间
using eval to import namespaces in javascript
我正试图用javascript将一个命名空间的内容转储到另一个命名空间中。我唯一能想到的直接做到这一点的方法如下:
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
将这些键及其相关值转储到Game
构造函数的作用域中。很多人告诉我不要使用eval
,但我看不到其他直接合并名称空间的方法。这不安全吗?对我来说,将棋子构造函数称为CHESSMEN
对象的属性会更好吗?
正如@zerkms所指出的,您应该使用CHESSMEN.Chariot
etc:来访问它们
var board = {
a1: new CHESSMAN.Chariot('red'),
b1: new CHESSMAN.Horse('red'),
c1: new CHESSMAN.Elephant('red'),
//etc.
此外,如果您要使用new
,您几乎肯定不希望以现有的方式实现Chariot
。你想要的模式是:
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"
}
我重申:这是一个坏主意。很难判断任何标识符指的是什么,它可能运行得更慢,而且它不兼容前向。有关详细信息,请参阅MDN。
至于eval的安全性:如果在以后的某个时候,你的代码发生了变化,使得CHESSMEN
可以具有用户定义的属性,那么攻击者可以将属性命名为foo; doHorriblyEvilThing();
,从而导致你的代码做出可怕的邪恶行为。
相关文章:
- 在javascript中使用命名空间
- javascript中的命名空间,IDE中支持代码完成/内容辅助's
- 如何使用javascript命名空间
- 转换自的JavaScript命名空间
- 什么's当前命名空间/类中JavaScript子命名空间/类的语法
- 在Firebug控制台中监视javascript命名空间变量
- 用自定义javascript全局命名空间替换窗口
- 怎么了?通过字符串定义 JavaScript 命名空间
- Javascript 命名空间/最佳实践
- IE中的Javascript命名空间抛出错误
- 处理此命名空间 JavaScript 结构的最佳方法是什么?
- 将 JavaScript 封装在命名空间中
- 将索引值传递给javascript命名空间数组
- JavaScript风格:我应该将这些东西中的哪些作为参数传递给我的命名空间函数
- 如何正确设置 JavaScript 命名空间和类
- 创建命名空间 Javascript 单例类的对象
- Xmlns 命名空间 JavaScript 删除
- 在我的命名空间JavaScript中使用this关键字
- 命名空间Javascript中的递归函数
- 构造函数-在简单的命名空间- Javascript