替代使用eval()

时间:2013-11-05 20:42:04

标签: javascript jquery arrays eval

我听过很多关于eval函数“邪恶”甚至“误解”的谣言,所以我决定将它从我的代码中删除。问题是我不知道该替换它。

这是我当前代码的快速概述。我在开头声明了一系列数组(下面的示例只有2个),然后基于按钮单击其中一个被加载到传递给函数的变量中。

这是一些基本的HTML

<div class="button" data-name="button1">Button1</div>
<div class="button" data-name="button2">Button2</div>

和JS(使用jQuery)

var butName = null;
var eArray = null;
var button1Logo = ["..path/to/pic1.png","..path/to/pic2.png"];
var button2Logo = ["..path/to/pic3.png","..path/to/pic4.png"];

    $(".button").mouseup(function(){
            /*give a butName*/
            butName = $(this).attr("data-name");

            /*give the array from the button*/
            eArray = eval(butName + "Logo");
    });

这样做会将数组分配给变量,而不仅仅是一个表示“butnameLogo”的字符串,这就是我使用eval的原因。但我希望摆脱这种局面。

我知道我可以为html添加一个新属性,只是为变量检索它,但是当我可以使用JS时,我不想添加更多的html。

我也尝试过将一个带有字符串的对象加载到它中,如下面的答案所示:https://stackoverflow.com/a/16038097/1621380但是这又产生了一个字符串,而不是分配变量。

想知道你是否聪明的人有更好的建议!

6 个答案:

答案 0 :(得分:8)

替换

var button1Logo = ["..path/to/pic1.png","..path/to/pic2.png"];
var button2Logo = ["..path/to/pic3.png","..path/to/pic4.png"];

使用对象,其中键是您的按钮名称:

var buttonLogos = {
    button1: ["..path/to/pic1.png","..path/to/pic2.png"],
    button2: ["..path/to/pic3.png","..path/to/pic4.png"]
};

然后您可以简单地执行<{p>}而不是eval

eArray = buttonLogos[butName]

(或buttonLogos[butName + "Logo"]如果您想调用密钥button1Logobutton2Logo,但我现在无法确切地看到它们很好地包含在{{1}中} object)

答案 1 :(得分:2)

最好的选择是定义一个包含所有按钮路径的对象:

var buttons = {
    "1": ["..path/to/pic1.png", "..path/to/pic2.png"],
    "2": ["..path/to/pic3.png", "..path/to/pic4.png"]
};
$(".button").mouseup(function(){
  /* give a butName */
  var butName = $(this).attr("data-name");

  /* give the array from the button */
  var eArray = buttons[butName];
});

<小时/> 如果您的变量位于全局范围内,则可以使用the bracket notation来访问它们:

eArray = window[butName + "Logo"];

注意建议不要使用此解决方案。第一个代码示例更清晰,更易于维护。

想象一种情况,你必须将所有代码移动到“更深层”的上下文(!=全局上下文)。什么都行不了了。

答案 2 :(得分:2)

使用对象:

var butName = null;
var buttonsLogos = {
      button1: ["..path/to/pic1.png", "..path/to/pic2.png"],
      button2: ["..path/to/pic3.png", "..path/to/pic4.png"]
};

$(".button").mouseup(function(){
    /*give a butName*/
    butName = $(this).attr("data-name");

    /*give the array from the button*/
    eArray = buttonsLogos[butName];
});

答案 3 :(得分:2)

考虑将数据作为对象的属性提供,然后您可以通过范围控制对对象的访问,并且只需要一个(全局?)变量用于所有此类数据。

如果需要全球范围,则:

var dataObj = {
    button1Logo: ["..path/to/pic1.png","..path/to/pic2.png"],
    button2Logo: ["..path/to/pic3.png","..path/to/pic4.png"]
}

以后:

var eArray = dataObj[this.data-name + 'Logo'];

您可能希望将数据对象称为比 dataObj 更有意义的内容。

答案 4 :(得分:1)

你可以很好地使用数组和数组索引。您根本无需查找和使用变量名称。即使您的data-属性也是不必要的。

var eArray;
var buttonLogos = [
    ["..path/to/pic1.png","..path/to/pic2.png"],
    ["..path/to/pic3.png","..path/to/pic4.png"]
];

var buttons = $(".button").mouseup(function(){
    var idx = buttons.index(this);

    eArray = buttonLogos[idx];
});

其中的关键行是buttons.index(this)。此方法调用获取$(".button")匹配的所有元素中当前元素的位置。然后,我们使用此索引从buttonLogos数组中选择相关元素。

答案 5 :(得分:1)

你在这里使用eval采取了非常迂回的路线。

你做这样的事情要好得多:

var paths = {
    button1: ["..path/to/pic1.png","..path/to/pic2.png"],
    button2: ["..path/to/pic3.png","..path/to/pic4.png"]
};

$(".button").mouseup(function(){
    /*give the array from the button*/
    eArray = paths[$(this).attr("data-name")];
});

eval只应在需要执行代码时使用(通常来自第三方来源),即使这种情况很少见。如果你发现自己说“我应该在这里使用eval”,那几乎肯定是一个更好的选择,你应该尝试找到它。