Javascript for..in循环参数ie.for(参数中的arg)在IE8中不起作用但它在Chrome 8中有效

sam*_*nta 8 javascript foreach internet-explorer arguments

我遇到了这种奇怪的情况,其中像javascript构造的foreach在IE中不起作用,但它在FF中工作.好吧,并非所有for..in这些特殊的功能都不起作用.我会发布代码.在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>
Run Code Online (Sandbox Code Playgroud)

更新我发布了一个错误的问题,它在FireFox中有效,但在IE8中没有,这是错误的.它在FireFox中也不起作用.实际上我从后期JavaScript获得此代码相当于printf/string.format.

Ken*_*iro 23

首先,虽然arguments函数中可用的对象不是数组,但它与"数组类似"足以使loop(for (var i = 0, len = arguments.length; i < len; i++) { ... })的增量更为可取 - 不仅因为它运行得更快,而且因为它避免了其他陷阱 -其中一个正是你所陷入的.

要真正回答为什么第二个循环不起作用的问题,重要的是要实现... in循环中的内容:它遍历在对象中找到的所有可枚举属性.现在,我在该陈述中加粗了两个字,因为我有目的地使用这两个词来表示一些细微差别,虽然它们看起来很微妙,但如果你没有意识到发生了什么,它们会极大地影响代码的行为. .

首先让我们关注所有 - 我的意思是说,不仅仅是对象本身的属性,还有潜在的属性,表示对象继承自其原型或原型的原型,等等.出于这个原因,通常建议您通过立即另外对条件进行限定if (obj.hasOwnProperty(p))(假设您的循环已写入for (var p in obj))来"保护"任何for ... in循环.

但那不是你在这里碰到的.为此,让我们关注第二个词,可枚举.JavaScript中对象的所有属性都是可枚举的或不可枚举的,这与属性是否出现在for ... in循环中非常直接相关.在Firefox和IE等浏览器中,事实证明,arguments对象的数字属性不是可枚举的(也不是它的length原样),这正是你没有迭代任何东西的原因!

但实际上,最后,为了迭代任何类似Array或类似数组的东西,你最好使用增量循环(如M. Kolodny所说),并完全避免这些恶作剧(更不用说潜在的跨浏览器)不一致 - 我似乎注意到在Chrome 10中,arguments对象的数字属性可枚举的!)