
本文讲解如何正确处理从 Google Sheets 等外部源读取的、被错误解析为字符串的嵌套数组(如 ["[{'city': 'ny'}]", ""]),并安全提取其中的 city 字段,避免 Cannot read properties of undefined 错误。
本文讲解如何正确处理从 google sheets 等外部源读取的、被错误解析为字符串的嵌套数组(如 `["[{'city': 'ny'}]", ""]`),并安全提取其中的 `city` 字段,避免 `cannot read properties of undefined` 错误。
在实际开发中(尤其是对接 Google Sheets、CSV 导入或低代码平台时),常遇到一种典型问题:本应是嵌套对象数组的数据(如 [[{city: 'ny'}], [{city: 'tx'}]]),却被意外转为字符串形式的数组字面量,例如:
const array = [
"[{'city': 'new york', 'state': 'ny'}]",
"[{'city': 'dallas', 'state': 'tx'}]",
"",
"[{'city': 'los angeles', 'state': 'ca'}]"
];
此时直接使用 item[0].city 会报错 TypeError: Cannot read properties of undefined (reading 'city'),因为 item 是字符串,item[0] 取的是首字符 '[',而非数组元素。
✅ 正确处理步骤
1. 安全解析每个字符串项
需对非空字符串项进行 JSON 解析。注意原始字符串使用单引号,而标准 JSON 要求双引号,因此需先替换:
const cities = array
.filter(item => item.trim() !== "") // 过滤空字符串
.map(str => {
try {
// 替换单引号为双引号,并去除首尾空白,再解析
const jsonStr = str.replace(/'/g, '"').trim();
const parsed = JSON.parse(jsonStr); // → [{city: "...", state: "..."}]
return parsed[0]?.city || null; // 安全取第一项的 city
} catch (e) {
console.warn("解析失败,跳过该项:", str, e);
return null;
}
})
.filter(city => city !== null);
console.log(cities);
// 输出: ['new york', 'dallas', 'los angeles']
2. 更健壮的解构写法(推荐)
若确认每项解析后均为长度为 1 的数组,可结合解构与可选链提升可读性:
const cities = array
.filter(str => str?.trim())
.map(str => {
try {
const arr = JSON.parse(str.replace(/'/g, '"'));
return Array.isArray(arr) && arr[0]?.city;
} catch {
return null;
}
})
.filter(Boolean); // 移除 null/undefined/falsy 值
⚠️ 注意事项
-
永远不要用
eval()或Function()解析不可信字符串 —— 存在严重 XSS 和执行风险; - Google Sheets 的
getValues()默认返回二维数组(如[['NY'], ['TX']]),若得到字符串数组,说明数据列被设为“文本”格式或经过了.toString()处理,建议源头改用Range.getDisplayValues()或预处理校验类型; - 若原始数据含特殊字符(如
"、\n),单引号→双引号替换可能失败,此时应要求上游提供标准 JSON 格式,或使用json5等宽松解析器(需额外引入); - 空项
[,]在 JS 数组字面量中会产生undefined元素(如[1, , 3]长度为 3,索引 1 为empty),但本例中是字符串"",需显式过滤。
✅ 总结
核心在于:识别数据真实类型 → 安全转换 → 防御性访问。从字符串化伪数组中提取结构化字段,必须经历「清洗 → 解析 → 解构 → 容错」四步。避免假设数据结构,始终用 try/catch 和可选链(?.)保护运行时安全。










