我仍然是JavaScript的新手(虽然不是为了编码),所以请随意为我挑选一些东西。
我试图创建一些接受用户输入的东西。如果第一个字符是感叹号,它将尝试创建具有该名称的对象并运行该对象的“action”方法。否则它会像常规文本一样对待(现在是警报)
<script type="text/javascript">
function GetInput(input){
// Trim the spaces off the beginning and end
input = input.trim();
if(input.charAt(0) != "!"){
// Just some normal text
alert(input);
return true;
}
/* Cut off the exclamation point, replace multiple spaces with one,
* and get the arguments if any. args[0] = the command. */
var args = input.substr(1).replace(/\s{2,}/g, " ").split(" ");
// Make sure the function is an object with a method named "action"
if(eval("typeof "+args[0]+";") === "function"
&& eval("typeof "+args[0]+".prototype.action;") === "function"){
eval("var command = new "+args[0]+"();");
command.action(args);
}else{
alert('"'+args[0]+'" is not a command.');
}
return true;
}
</script>
到目前为止,我注意到的唯一问题是eval语句。我知道我可以一起使用开关/盒子和沟槽eval,甚至可以创建一个包含允许函数名称的数组,并在eval之前将输入与该数组进行比较,但我确信必须有更好的方法
我只是想能够制作对象和方法而不更新任何东西(我认为这是鸭子打字的主要用途之一?)。没有评估这可能吗?如果没有,是否有一种简单的方法来清理字符串的输入,以避免“!eval(alert('u b haxed'))
”或“!a;alert('u b haxed')
”之类的内容?
提前致谢
答案 0 :(得分:2)
你应该只使用eval
一次来获取函数,然后在变量中用它做任何事情。
var args = input.substr(1).split(/\s+/);
var fn = eval(args[0]);
if (typeof fn == 'function' && typeof fn.prototype.action == 'function') {
var command = new fn();
command.action(args);
} else {
alert('"'+args[0]+'" could not be evaluated to a valid command.');
}
return true;
如果这些构造函数是全局变量,您也可以将它们作为window
对象的属性进行访问:
var fn = window[ args[0] ];