Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript for..in循环参数ie.for(arg in arguments)在IE8中不起作用,但在Chrome 8中起作用_Javascript_Internet Explorer_Foreach_Arguments - Fatal编程技术网

Javascript for..in循环参数ie.for(arg in arguments)在IE8中不起作用,但在Chrome 8中起作用

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>

我遇到了这样一种奇怪的情况:类似foreach的javascript构造在IE中不起作用,但在FF中起作用。不是所有的
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;
};