Javascript for..in循环参数ie.for(arg in arguments)在IE8中不起作用,但在Chrome 8中起作用
我遇到了这样一种奇怪的情况:类似foreach的javascript构造在IE中不起作用,但在FF中起作用。不是所有的Javascript for..in循环参数ie.for(arg in arguments)在IE8中不起作用,但在Chrome 8中起作用,javascript,internet-explorer,foreach,arguments,Javascript,Internet Explorer,Foreach,Arguments,我遇到了这样一种奇怪的情况:类似foreach的javascript构造在IE中不起作用,但在FF中起作用。不是所有的for..在中只是这个特殊的函数不起作用。我将发布代码。在IE8中测试。还使用XHTML DTD进行了测试 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> Test </TITLE>
for..在
中只是这个特殊的函数不起作用。我将发布代码。在IE8中测试。还使用XHTML DTD进行了测试
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> Test </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
</HEAD>
<script type="text/javascript">
<!--
String.prototype.format = function() {
var formatted = this;
var mycars = new Array(); //some
mycars[0] = "Saab";
mycars[1] = "Volvo";
mycars[2] = "BMW";
var arg;
for (arg in mycars) { alert('it comes here');
formatted = formatted.replace("{" + arg + "}", arguments[arg]); }
return formatted;
};
String.prototype.format2 = function() {
var formatted = this;
var arg;
for (arg in arguments) { alert('it does not come here');
formatted = formatted.replace("{" + arg + "}", arguments[arg]); }
return formatted;
};
function fn() {
var s = 'The {0} is dead. Don\'t code {0}. Code {1} that is open source!'.format('ASP', 'PHP');
alert('format:'+s);
var s2 = 'The {0} is dead. Don\'t code {0}. Code {1} that is open source!'.format2('ASP', 'PHP');
alert('format2:'+s2); //does not replace {0}s and {1}s
}
//-->
</script>
<BODY>
<input type="button" value="click " onclick="fn();" />
</BODY>
</HTML>
试验
更新我发布了一个错误的问题,它在FireFox中有效,但在IE8中无效,这是错误的。它在FireFox中也不起作用。事实上我是从邮局得到这个密码的 好吧,它应该能工作,所以如果不能,答案很简单,“这是IE中的另一个bug” 但这里真正的问题是为什么要使用
来。。。在
中,要迭代数组或类似数组的对象(例如参数
),只需使用一个简单的for
循环即可,该循环适用于所有主要浏览器:
for (var i = 0; i < arguments.length; i++) {
// do something with arguments[i]
}
for(变量i=0;i
尝试将其用作格式函数:
String.prototype.format = function() {
var me = this;
for (var i = 0; i < arguments.length; i++)
me = me.replace(new RegExp('\\{' + i + '\\}', 'g'), arguments[i]);
return me;
}
在IE中测试和工作从我的测试来看,Firefox 3.6.13和IE 8在行为上没有任何区别,它们都没有进入第二个循环 mycars和arguments之间的一个区别是mycars是一个数组,而arguments是一个对象 为了证明这一点:
alert(mycars.constructor); //shows: "function Array() { [native code] }"
alert(arguments.constructor); //shows: "function Object() { [native code] }"
然而,通过一些测试代码,我可以看到“for in”适用于数组和对象
var showWithForIn = function (myArgument) {
for (i in myArgument) {
alert(myArgument[i]);
}
};
var testArray = function() {
var mycars = new Array(); //some
mycars[0] = "Saab";
mycars[1] = "Volvo";
mycars[2] = "BMW";
showWithForIn(mycars);
};
var testObject = function() {
var myFriends = {
0: 'John',
1: 'Aileen'
};
showWithForIn(myFriends);
};
function testAll() {
testArray();
testObject();
}
所以,我不确定arguments对象与您自己用大括号构建的对象有何不同。我认为这是令人困惑的,因为在这个测试中,对数组和对象都有效。而“for in”不适用于参数
同样,在所有测试中,我都没有注意到FF3.6和IE8之间的任何差异
更新:由于Ken注释,我发现参数属性被定义为不可枚举,而定义对象时,文本属性被隐式定义为可枚举。首先,虽然函数中可用的
参数
对象不是数组,但它是“类似数组的”这足以让增量for循环(for(var i=0,len=arguments.length;i
)更可取——不仅因为它运行得更快,还因为它避免了其他陷阱——其中一个正是您所陷入的陷阱
要真正回答为什么第二个循环不起作用的问题,重要的是要了解它的用途。。。在循环中:它迭代对象中找到的所有可枚举属性。现在,我在这句话中加了两个粗体字,因为我故意用这两个字来表示一些细微差别,虽然它们看起来很微妙,但如果您不知道发生了什么,可能会极大地影响代码的行为
首先,让我们关注所有的——我的意思是说,不仅是对象本身的属性,还包括所述对象从其原型或其原型的原型继承的潜在属性,等等。出于这个原因,经常建议您“保护”任何。。。在循环中,立即使用条件if(obj.hasOwnProperty(p))
(假设您的循环是为(var p in obj)编写的)
但这不是你在这里遇到的。为此,让我们关注第二个词,可枚举性。JavaScript中对象的所有属性要么是可枚举的,要么是不可枚举的,这与该属性是否显示在for。。。是否在循环中。事实证明,在Firefox和IE等浏览器中,参数
对象的数值属性不可枚举(其长度也不可枚举),这正是您不进行迭代的原因
但实际上,最终,对于迭代任何数组或类似数组的内容,最好使用增量循环(正如M.Kolodny也指出的),并完全避免这些恶作剧(更不用说潜在的跨浏览器不一致性——我似乎注意到在Chrome 10中,参数
对象的数值属性是可枚举的!)有些浏览器支持for..in
像Chrome和Firefox 4这样迭代参数,但其他浏览器在这样迭代时看不到它的参数。我打赌在这些浏览器上,如果你使用JSON.stringify(参数)结果将是一个空对象。根据JavaScript 1.1规范和其他参数都有一个长度参数,这意味着您可以使用for(var i=0;i
和而(i
循环来迭代它们
就我个人而言,当我使用
for..forfor argument iteration时,我为argument object iteration编写了一个简单的函数,它不依赖于长度,因为参数总是按id顺序标记
var eachArg = function(args, fn, start_from, end_where) {
var i = start_from || 0;
while (args.hasOwnProperty(i)) {
if (end_where !== undefined && i === end_where)
return i;
if (fn !== undefined)
fn(i, args[i]);
i++;
}
return i;
};
从我迭代参数开始,我就一直使用它,而且它不会让我失望。更多关于它的信息,请参阅我的博客文章(i=0;i@Raynos:我非常怀疑IE的开发人员也能回答这个问题。@casablance我想找出答案。你能不能在你的示例代码中指出他在做的所有其他错误。你使用的是哪一版本的Firefox?对于FF 3.6.13和IE 8,我没有注意到任何行为上的差异,他们都没有进入第二个loop.@stivlo:实际上我没有测试代码。我只是说op无论如何都不应该在中为…使用
。我认为声称“这是IE中的另一个bug”是不正确的没有测试它,尤其是当FF有完全相同的行为时。你使用的是哪个版本的IE?我使用的是IE8、FF3.6.8和chrome 8.0.552谢谢你肯,+1有趣的答案,那么你知道为什么如果我用大括号构建对象,p
var eachArg = function(args, fn, start_from, end_where) {
var i = start_from || 0;
while (args.hasOwnProperty(i)) {
if (end_where !== undefined && i === end_where)
return i;
if (fn !== undefined)
fn(i, args[i]);
i++;
}
return i;
};