为什么数组偏移被认为是自己的属性?

时间:2015-11-12 23:19:15

标签: javascript arrays serialization

在我的序列化代码中,我偶然发现了一个棘手的问题 - 当我遍历通用对象属性时,它还会序列化数组索引,这实际上不是计划 - 我稍后将这些数据序列化而不保存流中的索引。

[1].hasOwnProperty("0") // true

所以我的问题是,为什么数组索引被hasOwnProperty方法视为自己的属性?有没有办法从数组偏移中告诉属性?一种通用方式,也适用于TypedArrayHTMLElementCollection以及其他什么方式?

当然,这可以做到,但它很臭:

  for(var i in this) {
    if(this.hasOwnProperty(i) &&
      // If object is an array, we ignore the number offsets as they're not meant to be object properties
      (typeof this.length!="number" || !(i<this.length) || i.length==0)) { 

是的,i.length==0就在那里,因为你实际上可以做到这一点:

var obj = {};
obj[""] = "something";
console.log(obj);

image description

是的,欢迎你,享受你的噩梦。

1 个答案:

答案 0 :(得分:2)

数组是对象,只是略微专业化。正如您所发现的,数组的索引只是名为0,1,2等的属性。

在一个非常简单的层面上,length属性只找到最高的数字属性并添加一个。

你可以按照

的方式稍微简化一下过滤键的方法
for (key in obj) {
    if (isNaN(+key) && obj.hasOwnProperty(key)) {
        doSomething()
    }
}

取决于您是否要包含对象的数字属性。执行a = {'0': 'value'}是完全有效的,这与本练习的目的相同b = ['value']。虽然b具有长度属性而a没有,但b也包含来自数组的所有其他函数。