JSON 数据遍历之 for-in

🕒 2026-01-29 14:49:23
📁 JSON学习教程
作者:JSONLA小编

本文核心讲解 JSON 数据遍历中for-in语句的使用规则、ECMAScript 规范的版本差异,以及for-in遍历 JSON 对象与数组的浏览器兼容问题,同时对比 JavaScript 中for循环与for-in遍历数组的核心区别,指出开发中的常见坑点并给出实用避坑建议,助力开发者规范使用遍历语法,避免因遍历问题导致的程序异常。

一、for-in 遍历 JSON 对象的核心规范:属性顺序无保障

JSON 对象本质是 JavaScript 中的普通对象,而对象本身是无序的属性集合,因此使用for-in语句遍历对象属性时,遍历出的属性顺序大概率与对象定义时的书写顺序不一致,这一特性与 ECMAScript(ES)规范的版本更新直接相关。

1. ECMAScript 规范版本差异

ECMA-262(ES3)第三版规范

明确描述:for-in语句的属性遍历顺序由对象定义时属性的书写顺序决定,此时遍历顺序是固定的,与定义顺序一致。

参考文档:ECMA-262 3rd Edition 中 12.6.4 The for-in Statement

ECMA-262(ES5)第五版规范对遍历机制做了关键调整:不再规定for-in的属性遍历顺序,将遍历顺序的决定权交给各浏览器的 JavaScript 解析引擎,引擎可自行实现遍历逻辑。

参考文档:ECMA-262 5rd Edition 中 12.6.4 The for-in Statement

2. 规范差异导致的开发问题

新版本规范与早期版本的说明冲突,使得遵循 ES3 规范实现的解析引擎(部分旧浏览器),和遵循 ES5 规范实现的解析引擎(现代浏览器),处理for-in语句时的属性遍历顺序不一致开发核心原则:应尽量避免编写依赖对象属性顺序的代码,否则会因浏览器解析引擎不同,出现遍历结果不一致的兼容问题。

3. 典型示例:JSON 对象与数组的 for-in 遍历差异 

var json1 = { "2":{"name":"第1条"}, "1":{"name":"第2条"}, "3":{"name":"第3条"} } var json2 = [ {"name":"第1条"}, {"name":"第2条"}, {"name":"第3条"} ] for(var i in json1){ alert(json1[i].name); } //正确 for(var i in json2){ alert(json2[i].name);  }   

关键说明

  • JSON 对象({}):无序结构,for-in遍历顺序不可控,严禁依赖遍历顺序处理业务;
  • JSON 数组([]):有序结构,for-in遍历虽能保证下标顺序,但仍存在其他坑点(下文详细说明)。

二、JS 循环遍历 JSON 数据的实际应用示例

实际开发中遇到的 JSON 数据分为纯数组型 JSON嵌套字符串型 JSON,两种格式的遍历方式略有差异,以下是具体的代码实现示例,覆盖常见的业务场景。

示例 1:纯数组型 JSON 数据的 for-in 遍历

直接定义数组型 JSON 数据,通过for-in遍历获取每个子对象的属性值,是最基础的 JSON 遍历方式:

var data=[{name:"a",age:12},{name:"b",age:11},{name:"c",age:13},{name:"d",age:14}]; for(var o in data){ alert(o); alert(data[o]); alert("text:"+data[o].name+" value:"+data[o].age ); }

示例 2:嵌套字符串型 JSON 数据的遍历

部分场景下,JSON 数据的属性值是JSON 格式的字符串(需先解析为可操作的 JSON 对象 / 数组),此时需通过eval()JSON.parse()解析后再遍历,以下是经典业务示例:

<script type="text/javascript"> 

function text(){ 

 var json = {"options":"[{/"text/":/"王家湾/",/"value/":/"9/"},{/"text/":/"李家湾/",/"value/":/"10/"},{/"text/":/"邵家湾/",/"value/":/"13/"}]"}  

 json = eval(json.options) 

 for(var i=0; i<json.length; i++) 

 { 

   alert(json[i].text+" " + json[i].value) 

 } 

</script>

JSON 字符串解析方式

示例中使用eval()解析 JSON 字符串,

现代开发更推荐使用JSON.parse(),原因如下:
  1. JSON.parse():专门用于解析标准 JSON 字符串,语法校验严格,若字符串格式不合法会直接抛出错误,安全性更高;
  2. eval():会执行字符串中的任意 JS 代码,若字符串包含恶意代码(如函数执行、变量赋值),会导致 XSS 安全漏洞,仅适用于可信数据源;
  3. 示例优化后的解析代码:json = JSON.parse(json.options);,效果与eval()一致,且更安全规范。

三、JavaScript 数组遍历:for 循环与 for-in 的核心区别详解

JS 中遍历数组有两种常用方式:标准 for 循环for-in 循环,看似能实现相同的遍历效果,但二者的底层逻辑、遍历机制存在本质区别,且在特定场景下执行结果差异极大,是开发中极易踩坑的点。

1. 基础遍历代码对比

var array = ['a'] //标准的for循环 for (var i = 1; i < array.length; i++) { alert(array[i]) } //foreach循环 for (var i in array) { alert(array[i]) }

 正常情况下,上述两种方式的遍历结果一致,均输出数组的所有元素,但二者存在多个底层区别,且在数组被扩展后会出现明显差异。

2. 基础区别:遍历变量的类型不同

  • 标准 for 循环中的i是number 类型,表示数组的下标,是纯数字索引;
  • for-in 循环中的i是string 类型,表示数组的键名,因为 JavaScript 中一切皆为对象,数组本质也是特殊的对象,下标只是数组的键名而已。
验证代码在遍历中添加alert(typeof i);可清晰看到变量类型的差异,这一区别在简单场景下影响较小,但在涉及数值计算时可能导致隐式类型转换问题。  

3. 核心区别:是否遍历数组原型上的扩展属性 / 方法

这是两种遍历方式最关键的区别,也是开发中最易引发 bug 的点。JavaScript 允许通过prototype扩展原生类的属性和方法,若数组(Array)的原型被扩展,for-in 循环会将扩展的属性 / 方法也遍历出来,而标准 for 循环仅遍历数组本身的元素。

示例:扩展 Array 原型后的遍历差异

// 扩展JavaScript原生的Array类,添加test方法 Array.prototype.test=function(){ } // 定义普通数组 var array = ['a', 'b', 'c'] // 方式1:标准的for循环 for (var i = 0; i < array.length; i++) { alert(array[i]) // 仅输出a、b、c,正常遍历数组元素 } // 方式2:for-in循环 for (var i in array) { alert(array[i]) // 输出a、b、c、test方法体,遍历了原型扩展的方法 }

现象说明

标准 for 循环仅遍历数组本身的索引元素,不受原型扩展的影响;而 for-in 循环会遍历数组对象的所有可枚举属性,包括数组自身的元素和原型上扩展的属性 / 方法,导致遍历结果包含非预期内容。

4. 差异根源:遍历机制不同(新增)

  • 标准 for 循环:通过数组下标主动遍历,仅访问array[0]、array[1]等合法下标对应的元素,完全基于数组的有序索引,不涉及对象属性的遍历;
  • for-in 循环:基于对象的可枚举属性遍历,数组作为特殊对象,其下标是 “数字型键名”,原型扩展的方法是 “字符串型键名”,for-in 会遍历所有可枚举的键名对应的属性,无论是否是数组本身的元素。
相关推荐

正在加载... ...