Javascript 如何使用JS数组元素定义对使用参数的函数的调用

Javascript 如何使用JS数组元素定义对使用参数的函数的调用,javascript,arrays,function,reference,Javascript,Arrays,Function,Reference,对于这个特殊的应用程序,我在一个折线图上绘制点,这些是我的函数用来将点放置在沿直线的正确位置上的数字 var CustomData = [ [168,36,10,1,"#FFFFFF","#f0e58d"], [282,31,10,1,"#FFFFFF","#559ab5"], [338,47,10,1,"#FFFFFF","#f0e58d"], [448,55,10,1,"#FFFFFF","#559ab5"], [540,49,10,1,"#FFFFFF","#559ab

对于这个特殊的应用程序,我在一个折线图上绘制点,这些是我的函数用来将点放置在沿直线的正确位置上的数字

var CustomData = [
  [168,36,10,1,"#FFFFFF","#f0e58d"],
  [282,31,10,1,"#FFFFFF","#559ab5"],
  [338,47,10,1,"#FFFFFF","#f0e58d"],
  [448,55,10,1,"#FFFFFF","#559ab5"],
  [540,49,10,1,"#FFFFFF","#559ab5"],
  [674,27,10,1,"#FFFFFF","#f0e58d"],
  [718,24,10,1,"#FFFFFF","#559ab5"],
  [846,24,10,1,"#FFFFFF","#f0e58d"],
  [1008,35,10,1,"#FFFFFF","#f0e58d"]
];
这些值的说明:

CustomData[index][x, y, radius, lineWeight, lineColor, fillColor];
我正在做的是使用CreateJS库来绘制这些形状,并使用简单的事件侦听器来检测单击事件(为了清晰起见,线被打断):

并将循环中的匿名函数更改为:

(function(i,shape,_i){
  shape.on("click", function() {
    window[_i[6]](i,_i);
  });
})(i,this.NewShape,_i);
我的问题是:这是实现这一目标的最佳、可扩展的方法吗?有什么我需要记住的“陷阱”吗?提前谢谢

这是实现这一目标的最佳可扩展方式吗

我不知道可伸缩性,但这不是实现这一点的最佳方式

有什么我需要记住的“陷阱”吗

通过将字符串存储在数组中,然后稍后在
窗口
对象上查找这些字符串,您将强制自己将所有函数设置为全局函数。全局名称空间已经非常非常拥挤,这可能导致冲突。在全局命名空间中放置的越多,可能遇到的冲突就越多

相反:

您可以像其他任何值一样将函数放置在数组中,因为函数可以通过表达式创建:

var CustomData = [
  [168,36,10,1,"#FFFFFF","#f0e58d", function() { /* do something */ }],
  [282,31,10,1,"#FFFFFF","#559ab5", function() { /* do something else */ }],
  [338,47,10,1,"#FFFFFF","#f0e58d", function() { /* do yet another thing */ }],
  // ...
];
如果您需要在多个条目上使用同一函数,或者如果您遇到可读性或维护问题,而长函数是这样内联定义的,您可能会发现单独定义函数然后在数组中引用它们更有用:

var CustomData = [
  [168,36,10,1,"#FFFFFF","#f0e58d", doSomething],
  [282,31,10,1,"#FFFFFF","#559ab5", doSomethingElse],
  [338,47,10,1,"#FFFFFF","#f0e58d", doYetAnotherThing],
  // ...
];

function doSomething() {
    // ...
}

function doSomethingElse() {
    // ...
}

function doYetAnotherThing() {
    // ...
}
即使在第二种情况下,如果您的代码位于作用域函数或模块中(无论是某种形式的库AMD还是ES2015模块),这些函数也不会是全局函数。(如果您只是将它们放在全局范围内,而不是scping函数或模块中,则它们将是。)

您可以像调用任何其他函数一样调用这些函数:

_i[6](arg1, arg2, arg3);
..我在这里使用
6
,因为在我上面的示例中,函数在这些数组中的索引6处


已经说过了,我建议您考虑使用“对象”而不是“数组”来处理<代码> >自定义数据> /COD>数组。< /P> 从您的问题中考虑以下代码:

this.NewShape.set({cursor:"pointer"});
this.NewShape.graphics.ss(_i[3]);
this.NewShape.graphics.s(_i[4]);
this.NewShape.graphics.f(_i[5]);
this.NewShape.graphics.dc(_i[0],_i[1],_i[2]);
比如说:

this.NewShape.set({cursor:"pointer"});
this.NewShape.graphics.ss(_i.ss);
this.NewShape.graphics.s(_i.s);
this.NewShape.graphics.f(_i.f);
this.NewShape.graphics.dc(_i.dc[0],_i.dc[1],_i.dc[2]);
您可以这样做:

var CustomData = [
  {dc: [168,36,10], ss: 1, s: "#FFFFFF", f: "#f0e58d", func: doSomething},
  {dc: [282,31,10], ss: 1, s: "#FFFFFF", f: "#559ab5", func: doSomethingElse},
  {dc: [338,47,10], ss: 1, s: "#FFFFFF", f: "#f0e58d", func: doYetAnotherThing},
  // ...
];
使用符号(
ss、
s
f
dc`)而不是索引通常会使事情更容易维护。更长、更有意义的名称可能更有用


关于在对象上创建方法并避免使用全局变量的问题,这里有一个相当标准的做法:

(function() {
    var stuff = {
        data: "Some value",

        method1: function() {
            // Do something, can reference data as `stuff.data`, e.g.:
            console.log(stuff.data);
            // If method1 is called via `stuff` (e.g., `stuff.method1()`),
            // it can also use `this.data`:
            console.log(this.data);
        },

        method2: function() {
            // Do something else...
        }
    };

    var otherStuff = {
        data: "Some other value",

        method3: function() {
            // Do something entirely different, possibly call `stuff.method2`:
            stuff.method2();
        }
    };

    // A standalone utility function
    function utilityFunction(arg) {
        return arg.toUpperCase();
    }

    stuff.method1();
    stuff.method2();

    otherStuff.method3();
})();
最外层的匿名函数是一个作用域函数,将其中声明的内容保持为私有<代码>填充、
更多填充
实用功能
都在该功能的范围内,但不在其范围之外

有时您可能会这样做,但希望公开一个符号(这通常称为“显示模块模式”,因为您只显示您希望公开的内容:

var stuff = (function() {
    // ...all that stuff above...

    return stuff;
})();
ES2015使这些方法声明更加简洁:

// ES2015 (aka ES6) and higher
var stuff = {
    method1() {
        // Do things here...
    }
};
……等等

var stuff = (function() {
    // ...all that stuff above...

    return stuff;
})();
// ES2015 (aka ES6) and higher
var stuff = {
    method1() {
        // Do things here...
    }
};