Javascript 如何从JSON数组调用函数

Javascript 如何从JSON数组调用函数,javascript,json,d3.js,Javascript,Json,D3.js,我试图弄清楚如何在我的项目中调用函数,而不用使用那么多if语句。使用if语句的概念非常有效。但是每次我创建一个新的函数调用时,我都必须编写一个新的if语句。我希望做的是在我的JSON数组中添加新的函数调用,并以这种方式调用我的函数。我目前正在通过D3从JSON数组加载数据,我希望通过这种方式添加函数调用。下面是我使用if语句的工作概念的副本,非常有效 var funcData; d3.csv("data/pointData5.csv", function(error, data) { fu

我试图弄清楚如何在我的项目中调用函数,而不用使用那么多if语句。使用if语句的概念非常有效。但是每次我创建一个新的函数调用时,我都必须编写一个新的if语句。我希望做的是在我的JSON数组中添加新的函数调用,并以这种方式调用我的函数。我目前正在通过D3从JSON数组加载数据,我希望通过这种方式添加函数调用。下面是我使用if语句的工作概念的副本,非常有效

 var funcData;

 d3.csv("data/pointData5.csv", function(error, data) {
funcData = JSON.parse(JSON.stringify(data));
     console.log(funcData);
     var select = d3.select("#selectL")
  .append("div")
  .append("select")
 select
 .on("change", function() {
var v = d3.select(this).property("value");
 if (v == 2) {
        updateDataA(); 
  }
 if (v == 3) {
        updateDataB(); 
  }
 if (v == 4) {
        updateDataC();
  }
 if (v == 5) {
        updateDataD(); 
      }
})
select.selectAll("option")
   .data(data)
   .enter()
   .append("option")
   .attr('class',  function(d,i) { return 'option' + i;})
   .attr("value", function (d) { return d.value; })
   .text(function (d) { return d.label; })
  });
下面是我试图开始工作的概念,但我似乎无法开始工作。函数名正在加载,但它不会像上面的脚本那样调用函数

var funcData;

d3.csv("data/pointData5.csv", function(error, data) {
funcData = JSON.parse(JSON.stringify(data));
console.log(funcData);
var select = d3.select("#selectL")
     .append("div")
     .append("select")
    select
        .on("change", function() {
        var v = d3.select(this).property("value");
        for (var i = 1; i <  funcData.length; i++)
    if (v == i && funcData[i].dataF) {
        console.log(funcData[i].dataF);
        funcData[i].dataF;
  }
})
select.selectAll("option")
    .data(data)
    .enter()
    .append("option")
    .attr('class',  function(d,i) { return 'option' + i;})
    .attr("value", function (d) { return d.value; })
    .text(function (d) { return d.label; })
});
下面是我的JSON数组的屏幕截图。

我真的很感激如果有人能提供一个解决方案,或者如果这个概念是可能的。先谢谢你

添加了函数调用内容的版本:

 updateDataA();

 function updateDataA() {
 updateData("gTank.png");
}
function updateDataB() {
updateData("bTank.png");
}
function updateDataC() {
updateData("diamond.svg");
}

////////////Add Markers to Map//////////////////
function updateData(url) {
removeMarkers()
omnivore.csv('data/pointData5.csv') 
    .on('ready', function(layer) {
    this.eachLayer(function(marker) {
         if (marker.toGeoJSON().properties.graphic != url) 
             marker.remove();
        //////////////////////////////////////////////////////////////
        // Add a flyTo button
        //////////////////////////////////////////////////////////////
          var button = document.createElement("button");
          button.className += " myBtns";
                if(marker.toGeoJSON().properties.graphic == url) {
                    button.innerHTML  = 
            marker.toGeoJSON().properties.cityName;
                    $('.zoomPoint').append(button);
        }
       // button.innerHTML = marker.toGeoJSON().properties.cityName;
        button.addEventListener("click", function (event) {
            event.preventDefault();
         // map.flyTo(layer.getLatLng(), 5); // This works obviously,
     but just to demonstrate use of xy conversion:
            map.flyTo(xy(marker.toGeoJSON().geometry.coordinates), 9, {
                animate: true,
                duration: 2.5
        });

          map.once("moveend", function () {
            marker.openPopup();
          });
        });

     ////////////////////////////////////////////////////////////// 


    //Load Icons from CSV file  
        var customIcon = L.icon({
            iconUrl: 'graphic/' + 
   marker.toGeoJSON().properties.graphic,//add graphic from CSV file
            iconSize: [20, 10 ], //size of the icon in pixels
            iconAnchor: [9, 9], //point of the icon which will
   correspond to marker's location (the center)
            popupAnchor: [0, 0] //point from which the popup should 
   open relative to the iconAnchor
  });
 //Add ID to each image - can now style each icon with CSS
 $('#map').find('img').each(function (i) {
$(this).attr('id', 'img_');
 });    

  $(".content ").find(".myBtns:first-child").prop("disabled", true);
         //change the icons for each point on the map
        marker.setIcon(customIcon);
         //create popup with text and image - click image in popup,
   large image displays in fancybox
        var popupText =
             marker.bindPopup('<strong>' +
  marker.toGeoJSON().properties.cityName + '</strong>' + ', ' + '</br>'
+ marker.toGeoJSON().properties.discrip +  "<br /><a class='fancybox- 
thumb' ' style='width:150px;' rel='fancybox-button'  rel='fancybox- 
 thumb' data-fancybox-group='"+ marker.toGeoJSON().properties.popup +"'
title='" + marker.toGeoJSON().properties.discrip + " '   
href='graphic/"+ 
marker.toGeoJSON().properties.popup + "' ><img src='graphic/" + 
marker.toGeoJSON().properties.popup + "' alt='Image' '  s
 style='width:150px;'
   ></a>" + "<br/><a href='http://www.google.com' 
     target='_blank'>Cedellion Report</a>");
   });
     }).addTo(map);
    }

可以将函数存储在数组中。但是有必要为调用添加括号

试一试

您还可以使用此代码在调用之前检查它是否为函数

if(typeof funcData[i].dataF === 'function') {
}
例子

您可以使用eval,但这是非常不鼓励的。有其他的选择可以做到这一点,但最有可能的是你可以在这里做一些重新架构。updateDataA、updateDataB和updateDataC函数的作用是什么?它们之间有多大的不同?最有可能的情况是,您可以重构一个updateData函数,该函数根据当前数组元素获取一个参数,并相应地更新数据。在我完全回答你的问题之前,我需要更多的细节

最好的方法是将URL存储在JSON数组中,例如URL:gTank.png,然后调用传递URL属性的updateData函数

let url = d3.select(this).property("url");
updateData(url);

这可能是最好的做法,因为eval是一种安全风险,非常不鼓励使用。

经过进一步研究,我找到了我的解决方案,eval。这是M.佩奇和里奇克的建议……谢谢。为了完成我想要完成的任务,我在循环中添加了如下函数:eval+funcData[I].dataF+;一切都如我所愿。谢谢大家让我走上正确的道路。

您能使用eval和看起来是您正在调用的函数名的值dataF吗?我阅读了该方法,并尝试了提供的一些示例,但无法使其工作。经过进一步研究,我找到了解决方案eval。这是M.佩奇和里奇克的建议……谢谢。为了完成我想要完成的任务,我在循环中添加了如下函数:eval+funcData[I].dataF+;一切都如我所愿。谢谢大家让我走上正确的道路。我修改了脚本,为调用添加了括号,但什么也没发生。但我有一个问题,我的JSON读取updateDataA;。我是否从JSON名称中删除括号?JSON现在的读取方式如下updateDataA。我试过那种方法,但效果不好。谢谢你的回复。我编辑了我的原始帖子,以包含我正在调用的函数的脚本。我使用CSV文件和D3来填充选项选择列表。我目前正在通过D3将CSV转换为JSON,并将数据放在一个全局变量中以调用函数,以替换我的if语句概念。这是M.佩奇和里奇克的建议……谢谢。为了完成我想要完成的任务,我在循环中添加了如下函数:eval+funcData[I].dataF+;一切都如我所愿。谢谢你们让我走上正确的道路。@TonyT不要使用eval。这是一个黑客的解决办法和安全风险。我之前提到过,这是非常令人沮丧的。在检查了你的updateData方法之后,我用一种合适的方法更新了我的答案。我把你的概念放进去了,效果很好。我对答案投了赞成票,因为它不仅有效,而且纠正了安全风险!!!!谢谢你的帮助。
let funcs = [
    (a, b) => { return a+b; },
    (a, b) => { return a-b; },
    () => { return true; }
];

funcs[0](2, 4); // return 6
funcs[1](2, 4); // return -2
funcs[2](); // return true
let funcs = {
    addition: (a, b) => { return a+b; },
    soustraction: (a, b) => { return a-b; }
};

funcs.addition(2, 4); // return 6
funcs['addition'](2, 4); // return 6
funcs.soustraction(2, 4); // return -2
funcs['soustraction'](2, 4); // return -2
let url = d3.select(this).property("url");
updateData(url);