【问题标题】:Puzzling javascript array behavior令人费解的 javascript 数组行为
【发布时间】:2010-11-15 11:03:47
【问题描述】:

所以,这可能是一个非常愚蠢的问题,但我显然在这里遗漏了一些东西。

考虑以下代码:

    var selectedItems = [];
    selectedItems.push("0ce49e98-a8aa-46ad-bc25-3a49d475e9d3");
    //fyi, selectedItems[selectedItems.length] = "0ce49e98-a8aa-46ad-bc25-3a49d475e9d3"; produced the same result.

最后selectedItems的内容是这样的:

Name              Value                                    Type
-------------     --------------------------------------   ------
selectedItems     {...}                                    Object
   -  [0]         "0ce49e98-a8aa-46ad-bc25-3a49d475e9d3"   String
   -  length      1                                        Long

但如果我只是尝试在同一个字符串上调用 split(),如下所示:

selectedItems = "0ce49e98-a8aa-46ad-bc25-3a49d475e9d3".split(",")

现在我假设的数组的内容看起来像这样(缺少长度):

Name              Value                                    Type
-------------     --------------------------------------   ------
selectedItems     {...}                                    Object
   -  [0]         "0ce49e98-a8aa-46ad-bc25-3a49d475e9d3"   String

知道有什么区别吗?这里到底发生了什么?
提前致谢。

更新: 我感觉这两个结果值实际上在结构上有所不同,因为当我尝试将它传递给服务器端 WebMethod 时(没有实际的错误消息,但我知道通话失败)。我不确定。

更新 #2 我注意到以这种方式设置 targetLocationIdList 会导致“快速监视”窗口中不显示“长度”属性:

  var params = 
  {
    jobId : args.get_JobId(), 
    targetLocationIdList : retVal.split(',')
  };

但此结果包含快速观察窗口中显示的“长度”属性:

  var retValArr = [];
  retValArr = retVal.split(',');

  var params = 
  {
    jobId : args.get_JobId(), 
    targetLocationIdList : retValArr 
  };

【问题讨论】:

  • "0ce49e98-a8aa-46ad-bc25-3a49d475e9d3".split(",").length === 1
  • 您能否发布任何示例代码,表明这实际上是您的调试器以外的其他地方的问题?

标签: asp.net javascript visual-studio ajax arrays


【解决方案1】:

以编程方式完全没有区别。如果您在 chrome 开发人员窗口和 firebug 中运行您的示例,它看起来像第二个

 Name              Value               
 Type
 -------------     --------------------------------------   ------ 
 selectedItems     {...}                                    Object
    -  [0]         "0ce49e98-a8aa-46ad-bc25-3a49d475e9d3"   String

长度是一个隐含的属性

编辑

var retVal = 'test';
var params = 
  {
    jobId : 1, 
    targetLocationIdList : retVal.split(',')
  }; 
console.log(params.targetLocationIdList.length) // prints 1

上面的代码在 IE8、Firefox、Chrome(在他们的开发工具或萤火虫中)打印 1,所以认为这一定是 Visual Studio 或 Atlas 显示对象的问题。

【讨论】:

  • 查看 edeverett 回答下的评论。谢谢。
  • 我在解释中添加了更多可能有用的内容
【解决方案2】:

这可能是调试器中的错误吗? (或者这会导致浏览器出现问题?)

【讨论】:

  • 是的,当我尝试从对话框弹出窗口中返回此值时,这确实会给我在 IE7 中带来问题。
  • 向我们展示不起作用的代码。我认为你一定做错了什么。在一种情况下,您可能正在查看字符串长度,而另一种情况是数组长度?无论如何,我们还没有足够的信息来提供帮助。
【解决方案3】:

在第一个实例中,您将 selectedItems 声明为一个数组,然后分配给它。

在第二种情况下,您直接从 split 方法分配给它。

我只能假设 VS 将数组声明作为显示长度属性的提示。

【讨论】:

    【解决方案4】:

    您似乎在 Microsoft 的 Javascript 实现中发现了一个缺陷。 Visual Studio 和 IE 可能共享相同的实现,这就是为什么您只在这两个程序中遇到错误,而不是在 Firefox 或 Chrome 中。

    在 EMCAScript 标准中:http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf

    15.5.4.14 String.prototype.split(分隔符、限制)
    返回一个 Array 对象,其中存储了将此对象转换为字符串的结果的子字符串。

    在Array Object的定义中:

    15.4 数组对象
    ... 每个 Array 对象都有一个长度属性,其值始终为非负整数 小于 232

    【讨论】:

      【解决方案5】:

      您使用的是什么浏览器,您确定没有length 属性吗?我刚刚做了

      var arr = "0ce49e98-a8aa-46ad-bc25-3a49d475e9d3".split(",")
      

      在我的 Firebug 控制台中,arr 确实有一个等于 1 的 length 属性,正如预期的那样。

      【讨论】:

      • 我正在 Visual Studio 2008 中调试。是的,如果我在代码中实际调用 arr.length,则可用的 length 属性准确显示为 1。但是在 arr 上进行快速观看,在这种情况下不会显示“长度”。
      • 听起来像是微软的缺陷
      • 也许吧。但我感觉这两个结果值实际上在结构上有所不同,因为当我尝试将它传递给服务器端 WebMethod 时(没有实际的错误消息,但我知道调用失败)。
      • 我只是在 Chrome 的控制台中查看了它,两个实体是相同的。我认为这是 Visual Studio 快速监视窗口。它可能认为一个是对象,另一个是数组(在 JavaScript 中数组和对象都报告为对象)。
      • 我同意这是一个 Visual Studio 问题,如果它实际上在它之外运行良好。但是 IE7 中的 asp.net ajax (atlas) 代码错误。明天我会尽力提供更详细的信息。
      【解决方案6】:

      你怎么知道调用失败了?确保您在调试模式下运行,或使用失败的处理程序来通知原因。

      【讨论】:

      • 我知道它失败了,因为代码执行在 asp.net ajax 代码中中断。可悲的是,有一个 try and finally 块,但没有捕获。 :)
      • 你的意思是有一个javascript错误——如果你让它运行,错误信息到底是什么?该 try/finally 块是处理来自服务器的响应的结果,因此您应该能够使用 Fiddler 来查看响应是什么,这也可能有一个重要的线索。
      • 不,它不处理来自服务器的响应——请求永远不会到达服务器。 try/finally 块在 asp.net ajax 的前端脚本中。
      • 没有错误信息,因为没有catch块——这就是问题所在。但我不打算去编辑和重建 asp.net ajax 程序集只是为了弄清楚这一点——不值得我花时间。我想也许有人已经遇到了类似的问题。
      • 没有catch不代表没有错误。在 javascript 中,没有捕获的 try/finally 具有隐藏原始错误来源的不幸副作用。就像它重置了堆栈,所以错误似乎来自 finally 块而不是它真正来自哪里。如果您只是让错误发生,您应该会在浏览器的错误列表中看到一些内容。现在,这在 FF 中可能不是真的,因为它报告错误的方式存在错误,我已经报告过但已经引起了很多关注,所以试试 IE。 Mozilla 错误如果有兴趣:bugzilla.mozilla.org/show_bug.cgi?id=377347
      【解决方案7】:

      这是一个非常简单的测试:

      var selectedItems = [];
      selectedItems.push("0ce49e98-a8aa-46ad-bc25-3a49d475e9d3");
      alert(selectedItems);
      selectedItems = "0ce49e98-a8aa-46ad-bc25-3a49d475e9d3".split(",");
      alert("boo");
      alert(selectedItems.length);
      

      boo 之后,我们检查是否还有长度。

      回答:是的。 所以换句话说,这是 Visual Studio 的错误,仅此而已。

      【讨论】:

      • 你们没注意。请参考 Vinay Sajip 的回答下的 cmets。
      猜你喜欢
      • 2011-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-30
      • 2018-07-02
      • 2020-06-19
      • 2023-03-12
      • 1970-01-01
      相关资源
      最近更新 更多