将一个数组通过使用点操作符添加值转换为对象(大写)

7
使用点号添加属性会将数组转换为对象吗?
var arr = [];

arr.something = "test";

这是一个数组吗?

我不这么认为,但underscore.js却说它是。

console.log( _.isArray(arr) );  //true

http://jsfiddle.net/wZcyG/


1
这是你正在使用的代码:http://underscorejs.org/docs/underscore.html#section-112 - Jason Sperske
1
我的猜测是,一旦你评估了这行代码 'arr = []',arr 的类型就被设置了。在下一次赋值之前,虚拟机就没有机会知道类型已经改变了。 - Jason Sperske
@Adi Inbar 那个标题是有意为之的。你为什么要编辑它?那不是指定它的正确方式吗? - 1252748
1
JavaScript中的Array是一个Object。问题在哪里? - idbehold
@thomas 你问添加一个属性到数组是否会将其变成对象,但是数组一直都是一个对象。所以它并没有改变。这就像问:“如果我在厨房里放一个厕所,它会变成一个房间吗?”……它一直都是一个房间。只是现在变成了一个奇怪的房间,因为厕所不是你通常放在厨房里的东西。 - idbehold
显示剩余5条评论
1个回答

7

如果你查看underscore.js 源代码,你会发现isArray函数被定义为:

 _.isArray = nativeIsArray || function(obj) {
    return toString.call(obj) == '[object Array]';
  };

浏览器的原生Array.isArray方法之所以说它是一个数组,是因为它的实例化对象就是数组。如果浏览器没有原生的isArray方法,underscore.js则使用第二个选项:比较对象上的toString方法返回的字符串是否为[object Array]
仅仅添加属性并不足以改变对象的类型(根据JavaScript虚拟机,它仍然是一个对象,恰好是一个数组)。JavaScript是一种动态语言,这意味着您可以向内置对象中添加属性,但是这样做并不会改变它们的本质;您只是在扩展它们。例如,Prototype.js曾通过向内置对象添加额外的属性(如迭代器、过滤器、映射函数等)来扩展它们。
您可以很容易地在Chrome中看到其行为:
> var arr = [];
  arr.something = "test";

> Array.isArray(arr);
  true

> toString.call(arr);
  "[object Array]"

编辑

该数组不会丢失其length属性:

> var arr = [1, 2, 3];
  arr.something = "test";
  console.log(arr.length, arr.something);

  3 "test"

请注意,浏览器正确报告了 3 的长度以及 something 属性的 test 正确值。

但它失去了length方法?那么它在某个基本层面上被改变了,对吗? - 1252748
将上述代码粘贴到您的控制台中。FF 表示它既具有长度为 0,也具有.something = test。 - Robert Hoffmann
哪个长度方法?length也是一个属性。 - supernova
1
@thomas 不,它不会失去其 length 属性。看看我的编辑。 - Vivin Paliath
1
不,我的“太对了”就是指这个。我现在明白了! - 1252748

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接