【问题标题】:array of objects: Cannot read property 'id' of undefined inside onchange event对象数组:无法读取 onchange 事件中未定义的属性“id”
【发布时间】:2018-12-09 20:31:30
【问题描述】:

如果 id 变量等于对象的 id,我已经搜索了一种从对象数组中删除单个对象的方法。

我使用数组来了解选择了哪些复选框,以便收集相关信息以进行进一步处理。

示例:https://jsbin.com/vicerewevi/edit?html,js,output

快速选择复选框时出现的错误:

Uncaught TypeError: Cannot read property 'id' of undefined
    at vicerewevi.js:33
    at Function.each (jquery-3.1.0.js:368)
    at HTMLInputElement.<anonymous> (vicerewevi.js:32)
    at HTMLInputElement.dispatch (jquery-3.1.0.js:5110)
    at HTMLInputElement.elemData.handle (jquery-3.1.0.js:4918)

如果 value.id == id 就出现上述错误:

// if checkbox is checked, add object to array and if unchecked remove object by 'id' from array
$('.checkbox').change( function(){

    var id = parseInt($(this).attr('data-id'))
    var foo = $(this).parent().siblings().find('#foo').val()
    var bar = $(this).parent().siblings().find('#bar').val()

    if($(this).prop('checked')) {
        var obj = {'id': id, 'foo': foo, 'bar': bar}
        jsonobjects.push(obj)
    } else {
        $.each(jsonobjects, function( index, value ) {
            if (value.id == id ) {
                jsonobjects.delete(index)
            }
        });
    }
    countChecked() // update count of checkboxes
    console.log(JSON.stringify(jsonobjects))
  $('#output').html(JSON.stringify(jsonobjects, null, ""))
});

我在我尝试过的 SO(以前从未使用过自定义原型)上找到了以下代码:

Array.prototype.delete = function(pos){
    this[pos] = undefined;
    var len = this.length - 1;
    for(var a = pos;a < this.length - 1;a++){
      this[a] = this[a+1];
    }
    this.pop();
  }

【问题讨论】:

  • 你试过用value.getAttribute("id") == id 代替value.id == id 吗?如果它是一个元素?
  • 顺便说一句,不用那种奇怪的delete方法,你可以直接用jsonobjects.splice(index, 1)
  • @JonasW。谢谢,我还在简单的 for 循环中添加了 hasownproperty 而不是 $.each 来检查数组中的元素是否不是数组函数

标签: javascript jquery arrays checkbox


【解决方案1】:

因为您是数组中的delete 条目,所以下次迭代它时,您将得到一个value,即数组中那个特定“间隙”的undefined。显然,它没有 id 属性。

要解决这个问题,不要使用delete,而是使用filter 创建一个新的过滤数组,它不会有这样的间隙。

替换:

    $.each(jsonobjects, function( index, value ) {
        if (value.id == id ) {
            jsonobjects.delete(index)
        }
    });

...与:

    jsonobjects = jsonobjects.filter(function( value ) {
        return value.id !== id;
    });

或者,如果您想坚持使用 jQuery 方法,请使用 $.grep

    jsonobjects = $.grep(jsonobjects, function( value ) {
        return value.id !== id;
    });

【讨论】:

    【解决方案2】:

    如果 id 变量等于对象的 id,我已经寻找一种方法从对象数组中删除单个对象。

    const arr = [
      { id: 0 },
      { id: 1 },
      { id: 2 },
      { id: 3 },
      { id: 4 },
      { id: 5 }
    ];
    
    const removeById = (arr, id) => arr.filter(e => e.id !== id);
    
    const no2 = removeById(arr, 2);
    const no5 = removeById(arr, 5);
    
    console.log(no2);
    console.log(no5);

    【讨论】:

      【解决方案3】:

      利用Array.filter 方法并像这样将jsonobjects 重新分配给过滤后的数组,而不是您创建的删除方法

      jsonObjects = jsonObjects.filter((value, index) => { return value.id !== id; }) 我希望这会有所帮助

      【讨论】:

        【解决方案4】:

        当我在这个 awnser For..In loops in JavaScript - key value pairs 上尝试解决方案时,这对我有用

        for (var k in jsonobjects){
            if (jsonobjects.hasOwnProperty(k)) {
                if (jsonobjects[k].id == id) {
                    jsonobjects.splice(k, 1)
                }
            }
        }
        

        【讨论】:

        • 如果jsonobjects 有两个连续的对象都具有您要删除的id 值,这可能会在数组中留下一个条目。在这种情况下,只会删除两者中的第一个,因为splice 将所有剩余元素向后移动一个索引位置,并且for 循环不会重新访问现在具有下一个项目的相同索引。参见例如this question & answer
        猜你喜欢
        • 1970-01-01
        • 2019-11-18
        • 1970-01-01
        • 1970-01-01
        • 2018-07-20
        • 2021-11-24
        • 2020-11-18
        • 1970-01-01
        • 2021-04-30
        相关资源
        最近更新 更多