TypeScript二维数组分组用户时push报undefined错误排查
错误根因
你遇到报错的核心是两个JS数组的基础认知错误:
- 第一,
new Array<User[]>(3)仅会生成一个长度为3的稀疏数组,数组的3个位置全是空位,不会自动给每个位置初始化空数组。这时候你访问任意索引位置拿到的都是undefined,对undefined调用push自然会抛出类型错误。很多刚从Java/C#转过来的开发者会误以为这个写法会生成填充了默认值的数组,实际上JS里这个API只做长度声明,不做元素填充。
- 第二,你的楼层编号从1开始计数,但JS数组的索引是从0开始的。如果你总共有N层楼,创建长度为N的数组时最大合法索引是N-1,直接拿floor=3去访问长度为3的数组,属于索引越界,同样会拿到
undefined。
另外你写的判断条件if (users[i].floor)存在隐性bug:如果有用户的floor值为0,会被这个falsy判断直接过滤掉,和本次报错无关但建议修正。
修复代码
初始化数组时手动给每个楼层位置填充空数组,同时适配1起始的楼层编号,加一层合法性校验避免异常楼层数据搞崩逻辑:
type User = { id: number; name: string; floor: number } // 总楼层常量N const FLOOR_COUNT = 3; class YourComponent { building: Array<User[]>; foo(users: User[]) { // 生成长度为N+1的数组,索引0闲置,1~N对应1到N层,每层初始化为空用户数组 this.building = Array.from({ length: FLOOR_COUNT + 1 }, () => [] as User[]); for (const user of users) { // 校验楼层合法性,跳过不在1~N范围内的异常数据 if (user.floor >= 1 && user.floor <= FLOOR_COUNT) { this.building[user.floor].push(user); } } } }
如果你不想浪费索引0的位置,也可以在存取的时候统一做floor - 1的偏移,把1层存在索引0的位置,逻辑是一致的。
内容的提问来源于stack exchange,提问作者Mortrus
相关产品推荐
相关产品推荐

