【问题标题】:Javascript array declaration: new Array(), new Array(3), ['a', 'b', 'c'] create arrays that behave differentlyJavascript 数组声明:new Array(), new Array(3), ['a', 'b', 'c'] 创建行为不同的数组
【发布时间】:2011-11-23 17:19:49
【问题描述】:

考虑这个示例 Javascript 代码:

a = new Array();
a['a1']='foo';
a['a2']='bar';

b = new Array(2);
b['b1']='foo';
b['b2']='bar';

c=['c1','c2','c3'];

console.log(a);
console.log(b);
console.log(c);

Firebug 控制台中的结果如下:

对于a(必须通过单击“+”按钮来扩展“[]”):

[]      
a1  "foo"   
a2  "bar"

对于 b:

[undefined, undefined]

对于 c:

["c1", "c2", "c3"]

我的问题是:

  1. 我是否正确使用了 array['key']='value' 语法?
  2. 为什么数组 b 没有按预期工作?
  3. 为什么数组 a 和 c 在控制台中显示不同?似乎 jQuery 也无法使用它的 .each() 方法遍历数组 a。
  4. 能否推荐一些关于 Javascript 数组行为的好教程?

注意:Google Chrome 的 Firebug 仅显示数组“a”的 [],没有扩展它的选项。

编辑:好吧,似乎 Javascript 中的数组只有数字键,所以添加一个字符串作为键名会使一个对象脱离数组。但是为什么 jQuery 的 .each 不能使用它呢?

$.each(a, function ()
    {
    alert ('derp');
    })

此代码附加到脚本中,不会产生任何警报。

【问题讨论】:

  • 您将 JavaScript 的数组对象与 PHP 等语言中可用的关联数组混淆了。 JavaScript 数组仅使用数字索引。使用语法a['a1'] = val 将属性a1 添加到对象a,而不是数组值。
  • @P.Brian.Mackey:可能是因为这类问题在 SO 上已经被问过很多次了。
  • @exizt:Firebug 和类似工具对您想要显示的内容做出假设。它们不一定是语言的完美表示,尽管如下所述,通常最好只依赖 JavaScript 数组中的数字属性。
  • @RightSaidFred - 你是说这个问题是重复的,但答案是新的?
  • 在这种情况下,究竟什么才是“研究”?你能告诉我我应该使用哪些搜索查询来找到正确的答案吗?

标签: javascript arrays syntax


【解决方案1】:

数组有数字索引。所以,

a = new Array();
a['a1']='foo';
a['a2']='bar';

and

b = new Array(2);
b['b1']='foo';
b['b2']='bar';

不是向数组添加元素,而是向a 对象添加.a1.a2 属性(数组也是对象)。作为进一步的证据,如果您这样做:

a = new Array();
a['a1']='foo';
a['a2']='bar';
console.log(a.length);   // outputs zero because there are no items in the array

您的第三个选项:

c=['c1','c2','c3'];

正在为变量c 分配一个包含三个元素的数组。这三个元素可以通过以下方式访问:c[0]c[1]c[2]。换句话说,c[0] === 'c1'c.length === 3

Javascript 不会将其数组功能用于其他语言所称的关联数组,您可以在数组中使用任何类型的键。您可以通过在 javascript 中使用一个对象来实现关联数组的大部分功能,其中每个项目只是这样的一个属性。

a = {};
a['a1']='foo';
a['a2']='bar';

为此目的使用数组通常是错误的,因为它只会使阅读您的代码的人感到困惑,并导致对代码如何工作的错误假设。

【讨论】:

  • 而关于ab 的区别,我认为它来自声明b = new Array(2);。在这里你说“我的数字索引数组有 2 个项目”。由于您没有在 b[0]b[1] 中添加任何内容,这就解释了您在 Firebug 中获得的 2 undefined
  • 我明白了,谢谢!但是为什么 jQuery 的 .each() 不能与 'a' 数组一起使用呢? (见编辑)
  • 有趣的是,firebug 将 a 视为包含数组元素的对象。但是,它将 b 视为没有可见属性的数组(尽管属性确实存在)。唯一的区别是传递给 Array 构造函数的参数。我想知道这是为什么?
  • @exizt - jQuery 的 .each() 方法必须尝试确定您传递给它的项目是对象还是数组,以便确定如何迭代它。如果它是一个数组,它使用.each() 迭代中的数组元素。在您的情况下,您给了它一个数组,因此它将它视为一个数组,但是该数组在实际数组中没有元素,因此没有什么可以迭代的。如果您更改为a = {}; 作为初始化,那么它将与jQuery 的.each() 一起使用。
  • @jfriend 在我的回答中澄清了我自己的疑问:P
【解决方案2】:

JS 中的数组有两种属性:

常规元素和关联属性(只不过是对象)

当您定义a = new Array() 时,您定义的是一个空数组。请注意,还没有关联对象

当您定义b = new Array(2) 时,您正在定义一个包含两个未定义位置的数组。

在您的“a”和“b”示例中,您正在向这些数组添加关联属性,即对象。

console.log (a)console.log(b) 分别打印数组元素,即 [][undefined, undefined]。但由于a1/a2b1/b2 是它们数组中的关联对象,它们只能通过console.log(a.a1, a.a2) 类型的语法来记录

【讨论】:

    猜你喜欢
    • 2010-11-17
    • 1970-01-01
    • 1970-01-01
    • 2020-07-19
    • 2015-08-14
    • 2021-07-10
    • 2021-02-08
    • 2022-12-27
    • 1970-01-01
    相关资源
    最近更新 更多