如何使用JS数组元素定义使用参数对函数的调用
How to Use JS Array Elements to Define Calls to Functions Using Arguments
对于这个特定的应用程序,我在折线图上绘制点,这些是我的函数用来将点放置在直线上正确位置的数字。
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库来绘制这些形状,并使用简单的事件侦听器来检测点击事件(为清晰起见,虚线):
for(i = 0; i < this.CustomData.length; i ++) {
var _i = this.CustomData[i];
this.NewShape = new cjs.Shape();
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]);
(function(i,shape,_i){
shape.on("click", function() { DoStuff(i,_i); });
})(i,this.NewShape,_i);
this.addChild(this.NewShape);
}
我想做的是扩展这个例程,这样我就可以在每个形状上使用一个自定义函数,我只是不知道如何在数组中定义对函数的引用。我还需要能够将迭代和CustomData
元素传递到函数中。
理论上,我想象的是:
var CustomData = [
[168,36,10,1,"#FFFFFF","#f0e58d", "DataFunc_A" ],
[282,31,10,1,"#FFFFFF","#559ab5", "DataFunc_B" ],
[338,47,10,1,"#FFFFFF","#f0e58d", "DataFunc_A" ],
[448,55,10,1,"#FFFFFF","#559ab5", "DataFunc_B" ],
[540,49,10,1,"#FFFFFF","#559ab5", "DataFunc_B" ],
[674,27,10,1,"#FFFFFF","#f0e58d", "DataFunc_A" ],
[718,24,10,1,"#FFFFFF","#559ab5", "DataFunc_B" ],
[846,24,10,1,"#FFFFFF","#f0e58d", "DataFunc_A" ],
[1008,35,10,1,"#FFFFFF","#f0e58d", "DataFunc_A" ]
];
并将循环中的匿名函数更改为:
(function(i,shape,_i){
shape.on("click", function() {
window[_i[6]](i,_i);
});
})(i,this.NewShape,_i);
我的问题是:这是实现这一目标的最佳、可扩展的方式吗?我需要记住什么"窍门"吗?提前谢谢。
这是实现这一目标的最佳、可扩展的方式吗?
我不知道可伸缩,但这不是实现这一点的最佳方式。
我需要记住什么"窍门"吗?
通过将字符串存储在数组中,然后稍后在window
对象上查找这些字符串,您就迫使自己将所有函数设为全局函数。全局命名空间已经非常非常拥挤,这导致了冲突的可能性。你在全局命名空间中放的越多,你遇到的冲突就越多。
相反:
您可以像其他任何值一样将函数放置在数组中,因为函数可以通过表达式创建:
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。
说了这么多,我建议您考虑使用对象而不是数组作为CustomData
数组中的条目。
从你的问题中考虑这个代码:
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();
})();
最外层的匿名函数是作用域函数,将其中声明的内容保持为私有。stuff
、moreStuff
和utilityFunction
都在该函数的范围内,但不在该函数之外
有时你可能会这样做,但想要暴露一个符号(这通常被称为"暴露模块模式",因为你只暴露你想要暴露的东西:
var stuff = (function() {
// ...all that stuff above...
return stuff;
})();
ES2015使这些方法声明更加简洁:
// ES2015 (aka ES6) and higher
var stuff = {
method1() {
// Do things here...
}
};
等等。
- 函数参数中的数据与指定变量之间的任何性能差异
- AngularJS:我可以跳过函数参数回调吗
- 函数未将值作为参数传递
- JS:检查URL中的参数,然后迭代一个参数为var的函数
- 为什么不'我们在javascript中使用函数参数的数据类型
- 你好,这是测试用例,我必须在函数中传递n个参数
- JavaScript - 多参数函数,它是多个图像库的字符串
- 如何从两个参数函数返回随机整数
- 以无点风格在Ramda中编写一个无参数函数
- JS:将单参数函数转换为可链接函数
- 正则表达式类似于Javascript中的参数函数
- 将 $' 值传递给替换的关联参数函数
- "这个“;在参数函数中
- 如何向jquery插件发送参数函数
- 将参数函数Node.js从一个js传递到另一个js
- 如何在javascript参数函数中传递PHP post方法字符串
- 装饰 Javascript Promise.then 以便参数函数接收附加参数
- 正在分析setInterval ID'是的's参数函数
- 如何根据一个参数函数计算年龄
- 对象参数/函数和/或三元运算符混淆