JavaScript - 自定义对象原型方法在数组循环中变成索引

3

有件奇怪的事情。我已经为object定义了一个自定义原型方法,名为getSize

if (!Object.prototype.getSize) {
    Object.prototype.getSize = function() {
        var size = 0, key;
        for (key in this) {
            if (this.hasOwnProperty(key)) size++;
        }
        return size;
    };
}

它给出了一个对象的大小。到目前为止,很简单,对吧?

接下来是我感到困惑的地方:

var l = ["foo", "bar"]
for (var i in l) {
    console.log(i);
}

结果如下:

0
1
getSize

为什么有getSize这个方法?

编辑 我知道JavaScript中的数组也是对象。我的问题是为什么这个方法变成了一个索引,而不是保持为一个方法。这对我来说毫无意义...

2个回答

4

getSize是一个可枚举的属性,你可以将其定义为不可枚举:

Object.defineProperty(Object.prototype, 'getSize', {
  enumerable: false,
  value: function() {
    var size = 0, key;
    for (key in this) {
      if (this.hasOwnProperty(key)) size++;
    }
    return size;
  }
});

但是你也可以这样做:
Object.keys(object).length;

我不知道方法有一个“可枚举”的定义。这很酷,谢谢你的答案!从现在开始我会使用defineProperty - yuvi
顺便提一下,即使我没有设置enumerable: falseObject.keys(l)返回['0','1'] 甚至在这里 - 为什么? - yuvi
@yuvi 因为 Object.keys 不使用原型链。所有这些东西都在 MDN 上有很好的文档记录。 - Dagg Nabbit
@DaggNabbit 谢谢。MDN文档很详细,但这并不意味着你总是知道该去哪里查找或者某个东西的含义。显然,Object.keys不会像for...in一样经过相同的过程,否则你将得到相同的结果。我想知道那个过程是什么(或者那是在代码的非常低层次上发生的吗?) - yuvi

3
因为["foo", "bar"]在JavaScript中也是一个对象。尝试在控制台中运行typeof ["foo", "bar"]。它会返回"object"给你。所以你也扩展了数组方法。一旦你完成了这个,你需要在所有的for..in迭代中检查hasOwnProperty
这种情况发生在JavaScript中的所有全局对象

我知道数组也是对象。但为什么它没有继承方法,而被转化成了索引?这毫无意义。 - yuvi
1
elclanrs的回答。你可以在MDN上阅读关于可枚举性和属性所有权的更多内容:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties。 - antyrat

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