具有 JavaScript 过滤功能的堆栈溢出

Stack Overflow With JavaScript Filter Function

大家好,我正在尝试用 JavaScript 中的对象模拟一个数组。我认为用 getter 模仿长度函数会很容易,但看起来我的过滤函数导致堆栈溢出。出于某种原因,我不知道出了什么问题。你能发现错误吗?

const o = {
  0: 'hello',
  1: 'there',
  fakeLen: () => {
    return Object.keys(this).length
  },
  get length() {

    const keys = Object.keys(this);
    const filtered = keys.filter(key => typeof this[key] != 'function');
    console.log('filtered array ', filtered);
    return filtered.length;
  }

};

console.log('correct?  ', o.length);
console.log('wrong? ', o.fakeLen());

也许我只是累了,但我没有看到过滤器函数如何导致堆栈溢出!

正确的方法

const o = {
  fn: function () {},
  0: 'hello',
  1: 'there',
  fakeLen: function() { // NOT ARROW FN
    return Object.keys(this).length
  }
};
// define getter
Object.defineProperty(o, 'length', {
  enumerable: false,
  get: function() {
    const keys = Object.keys(this);
    const filtered = keys.filter((key) => {
      console.log(this[key], typeof this[key])
      return typeof this[key] !== 'function'
    });
    console.log('filtered array ', filtered);
    console.log('filtered.length', filtered.length)
    return filtered.length;
  }
})

console.log('length  ', o.length);
console.log('fakeLen ', o.fakeLen());

当您在 this 上调用 Object.keys() 方法时,您将获得对象内的所有属性,因此 keys 将如下所示:

["0", "1", "fakeLen", "length"]

然后,当您过滤每个键时,您在上述数组中的每个元素上使用括号表示法。因此,您将执行以下操作:

typeof this["length"] != 'function'

因为length是一个getter(由于get),this["length"]会导致你的length方法再次被调用,从而重复直到出现堆栈溢出为止。

const o = {
  get length(){
    this["length"];
  }
};

o.length

您可以使 length 属性 不可枚举(如 Medet Tleukabiluly 所示),这样当您对其调用 Object.keys() 时,它不会出现在您的 keys 列表,或者,您可以在过滤之前简单地从密钥中删除 "length"

const o = {
  0: 'hello',
  1: 'there',
  get length() {
    const keys = Object.keys(this).filter(key => key !== "length");
    const filtered = keys.filter(key => typeof this[key] != 'function');
    return filtered.length;
  }

};

console.log(o.length);