我有一些看起来像这样的代码:
function StrippedExample(i1, i2, i3, i4, i5, i6, i7, i8) {
this.i = [];
for (var i=1,j=0 ;i<9;i++) {
var k = eval("i"+i);
if (k > 0) {
this.i[j++] = k;
}
}
}
FireBug Profiler声称第二个最长的函数是eval(),占运行时间的近6%。
Everyone says eval is EVIL(好像坏)和慢(我发现),但我不能做任何其他事情 - 服务器只是将数据从数据库中拉出并推送到浏览器。
我有哪些替代方案?我可以像在服务器上这样做一样,但这只会将负担转移到链条上方。我无法改变数据库布局,因为所有内容都挂钩到这8个变量,这是一项艰巨的任务。
答案 0 :(得分:14)
function StrippedExample(i1, i2, i3, i4, i5, i6, i7, i8) {
var args = [i1, i2, i3, i4, i5, i6, i7, i8]; // put values in an array
this.i = [];
for (var i=0,j=0 ;i<8;i++) { // now i goes from 0-7 also
var k = args[i]; // get values out
if (k > 0) {
this.i[j++] = k;
}
}
}
上面的代码可以进一步简化,我只做了最小的改动以摆脱eval
。你可以摆脱j
,例如:
function StrippedExample(i1, i2, i3, i4, i5, i6, i7, i8) {
var args = [i1, i2, i3, i4, i5, i6, i7, i8];
this.i = [];
for (var i = 0; i < args.length; i++) {
var k = args[i];
if (k > 0) { this.i.push(k); }
}
}
是等价的。或者,使用内置的arguments
对象(以避免将参数列表放在两个位置):
function StrippedExample(i1, i2, i3, i4, i5, i6, i7, i8) {
this.i = [];
for (var i = 1; i < arguments.length; i++) {
var k = arguments[i];
if (k > 0) { this.i.push(k); }
}
}
即使您没有过滤列表,也不希望执行this.i = arguments
之类的操作,因为arguments
不是真正的数组;它有一个你不需要的callee
属性,并且缺少i
中可能需要的一些数组方法。正如其他人所指出的,如果你想快速将arguments
对象转换为数组,你可以用这个表达式来实现:
Array.prototype.slice.call(arguments)
您可以使用它而不是上面的var args = [i1, i2 ...
行。
答案 1 :(得分:7)
您只是从函数8参数中创建一个数组,删除小于或等于零的数组。
以下代码是等效的,它适用于任意数量的参数:
function StrippedExample() {
var args = [];
for (var i = 0; i < arguments.length; i++) {
if (arguments[i] > 0) {
args.push(arguments[i]);
}
}
//...
}
答案 2 :(得分:5)
答案 3 :(得分:4)
将数组传递给函数的一种替代方法,而不是单个参数:
StrippedExample([3, 1, 4, 1, 5, 9, 2, 6])
然后你的代码将是:
function StrippedExample(inArray) {
this.i = [];
for (var i=0,j=0 ;i<inArray.length;i++) {
var k = inArray[i];
if (k > 0) {
this.i[j++] = k;
}
}
}
如果你真的需要传入单独的参数,你可以使用你的arguments
数组来访问它们,这个数组就像一个数组(虽然它不是真的;不是所有的数组方法都可以使用它)公开已传入函数的所有参数;在这种情况下甚至不需要声明它们,但是包含一个注释可以很好地形成一个注释,表明您希望代码的用户有哪些类型的参数:
function StrippedExample(/*i1, i2, i3, i4, i5, i6, i7, i8*/) {
this.i = [];
for (var i=0,j=0 ;i<arguments.length;i++) {
var k = arguments[i];
if (k > 0) {
this.i[j++] = k;
}
}
}
如果您保证只有8个元素,那么您可以使用8
代替inArray.length
或arguments.length
;我决定在我的示例中使用更通用的版本,以防对您有所帮助。
答案 4 :(得分:1)
此代码应该使用每个Javascript函数都可以访问的arguments
数组。
并不是eval
邪恶(它在Lisp中,所以它一定是好)它只是一个黑客的标志 - 你需要一些东西工作,你强迫它。它向我尖叫“作者放弃了良好的编程设计,只是发现了一些有用的东西。”
答案 5 :(得分:1)
function StrippedExample() {
this.i = [];
for (var i=1,j=0 ;i<arguments.length;i++) {
var k = arguments[i];
if (k > 0) {
this.i[j++] = k;
}
}
}
答案 6 :(得分:1)
Eval替代方案:
hello
这是你要找的吗?
答案 7 :(得分:0)
鉴于存在固定数量的变量,您可以手动构建它们的数组并循环遍历它。但是如果你有一个可变数量的参数,一种方法是将变量作为数组传递给函数:
var args = Array.prototype.slice.call(arguments.callee.caller.arguments);
你的功能看起来像这样:
function StrippedExample() {
var args = Array.prototype.slice.call(arguments.callee.caller.arguments);
for(var i in args) {
if (args[i] > 0) {
this.i[j++] = args[i];
}
}
}
答案 8 :(得分:0)
StrippedExample=(...a)=>a.filter(i=>i>0);
根本不需要使用 eval 来处理参数。
答案 9 :(得分:-1)
绝对可以尝试将其作为替换产品。 我一直在寻找这个答案,并来到了这篇文章。 我阅读了开发人员文档,并且可以直接替换为我的应用程序
var func1 =“ stringtxt” +对象+“ stringtxt”;
而不是---> eval(func1); ->使用-> Function(func1)();
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Never_use_eval!