JS报错undefined is not an object:Safari正常Chrome及线上环境图标色保存失效
问题修复方案
报错根源
populateState函数未做边界判断,直接链式访问currentState[key][type],当localStorage中无对应存储数据、currentState[key]为undefined时,访问其下的type属性就会抛出该类型错误。Safari本地环境能正常运行大概率是因为之前调试时已经在localStorage中写入了合法的初始化数据,而Chrome和线上环境的localStorage为空,所以触发报错。clickity函数初始化属性时存在语法错误:写为{type: false}时,键名type会被识别为固定字符串,而非你声明的type变量值,导致实际存储的属性名和后续读取的type值不匹配,也会触发属性读取失败的问题。
修复后完整代码
const currentState = JSON.parse(localStorage.getItem("selectionState") || '{}'); const getKeyType = el => { return [el.parentNode.id, el.dataset.type]; } const populateState = el => { const [key, type] = getKeyType(el); // 增加可选链和默认值,避免读取undefined属性 const isActive = currentState[key]?.[type] ?? false; el.style.color = isActive ? el.dataset.activeColor : el.dataset.disabledColor; }; const clickity = function () { const [key, type] = getKeyType(this); if (!currentState.hasOwnProperty(key)) { // 使用计算属性名,用type变量的值作为键名 currentState[key] = {[type]: false}; } else if (!currentState[key].hasOwnProperty(type)) { // 新增同key下不同type的初始化逻辑 currentState[key][type] = false; } currentState[key][type] = !currentState[key][type]; populateState(this); localStorage.setItem("selectionState", JSON.stringify(currentState)); } const buttons = document.querySelectorAll("i"); for (const button of buttons) { populateState(button); button.addEventListener('click', clickity); }
额外优化说明
- 新增了同key下新增不同type时的初始化逻辑,避免后续新增按钮类型时再次触发同类报错
- 用
const声明key和type变量,避免隐式全局变量污染
内容的提问来源于stack exchange,提问作者Tommy Andersen
相关产品推荐
相关产品推荐

