JS renderCitySelectors读取cityName报undefined类型错误修复
Uncaught TypeError: Cannot read properties of undefined (reading 'cityName') 修复方案
根因
报错100%复现于本地存储的历史城市数量小于3的场景,问题出在renderCitySelectors函数的循环逻辑:
- 循环索引起始值硬编码为
length-3,当数组长度小于3时,起始索引为负数 - JS里访问数组的负索引不会直接报错,只会返回
undefined,后续读取undefined的cityName属性就会抛出你看到的类型错误 - 之前修复只验证了存够3个城市的场景,没覆盖新用户首次访问、清空缓存、历史城市不足3个的情况,所以问题反复出现。
附带隐性问题
代码里还有两个未触发的潜在bug,可一并修复:
getWeather函数里在weatherMainButton、weatherDescriptionButton声明前就把变量传给了empty()方法,会触发变量未定义的引用错误- 歌单匹配逻辑只判断温度,40-80度区间直接返回雨天歌单,没有结合天气描述字段匹配,不符合预期功能。
修复代码
1. 重写renderCitySelectors函数,补全边界判断
var renderCitySelectors = function() { // 先清空容器,避免重复渲染按钮 $("#city-buttons").empty(); var length = cityObjArray.length; console.log("***************************************cityObjArray=", cityObjArray); // 计算起始索引:最多展示最近3个历史城市,不足3个从数组第一位开始遍历 const startIndex = Math.max(0, length - 3); for (let arrayIndex = startIndex; arrayIndex < length; arrayIndex++){ const currentCity = cityObjArray[arrayIndex]; // 加兜底判断,兼容localStorage被手动篡改的脏数据场景 if (currentCity && currentCity.cityName) { appendCity(currentCity.cityName); } } }
2. 修正getWeather里的DOM操作顺序
找到原错序代码段:
// 原错误代码:变量还没声明就传给empty方法 $("#weather-main").empty(weatherMainButton); $("#weather-description").empty(weatherDescriptionButton); var weatherMainButton = $("<button class=button></button>").text(weatherMain); $("#weather-main").append(weatherMainButton); var weatherDescriptionButton = $("<button class=button></button>").text(weatherDescription); $("#weather-description").append(weatherDescriptionButton);
替换为正确顺序的代码:
// 先清空容器,再创建、追加新元素 $("#weather-main").empty(); $("#weather-description").empty(); var weatherMainButton = $("<button class=button></button>").text(weatherMain); $("#weather-main").append(weatherMainButton); var weatherDescriptionButton = $("<button class=button></button>").text(weatherDescription); $("#weather-description").append(weatherDescriptionButton);
3. (可选)优化歌单匹配逻辑
如果要符合“根据天气+温度匹配歌单”的预期,可以调整getPlaylist的判断规则,结合weatherMain字段判断晴天/雨天/雪天场景,而不是只靠温度硬编码返回结果。
验证步骤
- 打开浏览器控制台,执行
localStorage.removeItem("cityInfo")清空历史缓存,刷新页面确认无报错 - 依次添加1、2、3、4个城市,确认历史按钮渲染正常,控制台无报错
- 点击历史城市按钮,确认天气接口、Spotify接口请求正常
内容的提问来源于stack exchange,提问作者babaphillips
相关产品推荐
相关产品推荐

