hasOwnProperty 的行为不符合预期

问题:在循环体中hasOwnProperty 始终返回false

期望:属性为非原型属性时进行下一步操作

相关代码

Array.prototype.groupBy = function (cb, ctx = window) {
      if (this === null || !Array.isArray(this)) {
        throw TypeError('此方法是数组原型方法,你应该对数组调用它');
      }
      if (typeof cb !== "function") {
        throw TypeError("你应该传入回调函数,而不是什么别的类型");
      }

      var key;
      var resultObj = {};
      for (var i = 0; i < this.length; i++) {
        key = cb.call(ctx, this[i], i, this);
        console.log(this[i].hasOwnProperty(key)); // undefined
        // 这里只有在for in循环中才会生效
        if(this[i].hasOwnProperty(key)) {
          resultObj[key] = [];
          resultObj[key].push(this[i]);
        }
      }
      return resultObj;
    }
    const invent = [
      { name: 'apples', type: 'vegetables', quantity: 5 },
      { name: 'bananas', type: 'fruit', quantity: 0 },
      { name: 'goat', type: 'meat', quantity: 23 },
      { name: 'cherries', type: 'fruit', quantity: 5 },
      { name: 'fish', type: 'meat', quantity: 22 }
    ];

    var res = invent.groupBy(function (item) {
      return item.type
    })
    console.log(res);
阅读 1.7k
2 个回答

如果期望是groupBy('type')这样的,可以这么写:

Array.prototype.groupBy = function (property) {
  if (this === null || !Array.isArray(this)) {
    throw TypeError('此方法是数组原型方法,你应该对数组调用它');
  }
  if (typeof property !== "string") {
    throw TypeError("需要字符串");
  }
  let result = {}
  for (let i = this.length-1;i>=0;i--) {
    const item = this[i]
    if(item.hasOwnProperty(property)){
      let temp = result[item[property]]
      if(temp){
        temp.push(item)
      }else{
        result[item[property]] = [item]
      }
    }
  }
  return result
}

如果期望是groupBy(item => item.type)这样的,可以这么写:

Array.prototype.groupBy = function (cb) {
  if (this === null || !Array.isArray(this)) {
    throw TypeError('此方法是数组原型方法,你应该对数组调用它');
  }
  if (typeof cb !== "function") {
    throw TypeError("需要函数");
  }
  let result = {}
  for (let i = this.length-1;i>=0;i--) {
    let key = cb.call(null, this[i])
    if(result[key]){
      result[key].push(this[i])
    }else{
      result[key] = [this[i]]
    }
  }
  return result
}

没做边界处理啥的,不要纠结那么多。

PS:当你发现你的代码没有如期运行,可以多打印一些上下文,比如你的例子中,多打印一下this[i]和key,应该能很快找到思路

你应该是想根据type的值来分组,根本不需要hasOwnProperty

const resultObj = {};
for (let i = 0; i < this.length; i++) {
    const key = cb.call(ctx, this[i], i, this); // 可以优化判断返回值为字符串或者数字
    if(!resultObj[key]) resultObj[key] = [];
      resultObj[key].push(this[i]);
}
return resultObj;
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题