使用<=运算符报Cannot read properties of undefined(sender)错误
问题根因说明
这个报错是数组索引越界导致的,和any[]类型声明无关,你对&&短路逻辑的作用边界判断有误,具体拆解如下:
- 首先明确JavaScript数组的基础规则:长度为
n的数组,合法可访问的索引范围是0到n-1,访问超出这个范围的索引会返回undefined。 - 你在
isSameSender函数中,边界判断后执行的是messages[index + 1].sender._id,这行代码要访问的是index+1位置的元素,要求index+1必须落在合法索引范围内,也就是index+1 <= messages.length -1,换算后就是index <= messages.length -2,等价于index < messages.length -1。 - 当你把判断条件写为
index <= messages.length -1时,当index等于数组最后一个元素的索引(也就是messages.length-1),边界判断返回true,&&不会触发短路,会继续执行后续代码:此时index+1 === messages.length,这个位置在数组中不存在,值为undefined,读取undefined的sender属性就会抛出你看到的错误。 - 当你把判断符换成
<,写成index < messages.length -1时,只要index等于最后一个元素的索引,边界判断就会返回false,&&直接短路返回结果,不会执行后续访问index+1位置的代码,自然不会触发越界错误。
额外说明
&&的短路逻辑本身没有问题,规则是:从左到右执行条件,遇到第一个false就停止执行后续条件,直接返回false;所有条件都为true才返回true。你的问题是边界判断没有匹配后续代码的访问范围,只判断了index本身是合法索引,没有考虑到后续要访问的是index+1位置的元素。any[]类型不会触发这个运行时错误,它的影响是让TypeScript跳过类型校验,无法在编译阶段提前提示你索引越界的风险。如果给消息定义明确的接口类型,这类越界问题可以在写代码时就被TS检测出来。- 你写的
isLastMessage函数边界判断逻辑有冗余:这个函数的作用是判断当前索引是不是最后一条消息,不需要用<=判断范围,直接判断index === messages.length -1即可,修正后的完整代码如下:
export const isSameSender = ( messages: any[], message: any, index: number, user: IUser ) => { return ( index < messages.length - 1 && messages[index + 1].sender._id === message.sender._id && messages[index].sender._id !== user._id ) } export const isLastMessage = (messages: any[], index: number, user: IUser) => { return index === messages.length - 1 && messages[index].sender._id !== user._id }
内容的提问来源于stack exchange,提问作者Milan Poudel
相关产品推荐
相关产品推荐

