js对象平铺的两种表现方式

本文探讨了JavaScript中处理多维对象平铺的两种常见方式。第一种是将多维对象转换为扁平结构,第二种则涉及特定的平铺形式。通过示例代码展示了如何实现这两种方法。

一、常规的平铺需求。

  给出一个多维对象

  

var obj = {
                eureka1: {
                    clinet: {
                        clinetclient: 70,
                        healthcheck1: {
                            enabled: true
                        },
                        serviceUrl: "http://dsfasdf"
                    },
                    instance: {
                        health: "/health",
                        hostname: "${hostname}",
                        prefer: true,
                        statuspath: "/info"
                    },
                    server: {
                        enabledvation: false,
                        peer: 6000
                    }
                },
                eureka2: {
                    health: {
                        status: {
                            order: "DOWN,UP"
                        }
                    }
                }
            }

  需要转换的形式为:

      

 

  js方法:

        

<script>
            var obj = {
                eureka1: {
                    clinet: {
                        clinetclient: 70,
                        healthcheck1: {
                            enabled: true
                        },
                        serviceUrl: "http://dsfasdf"
                    },
                    instance: {
                        health: "/health",
                        hostname: "${hostname}",
                        prefer: true,
                        statuspath: "/info"
                    },
                    server: {
                        enabledvation: false,
                        peer: 6000
                    }
                },
                eureka2: {
                    health: {
                        status: {
                            order: "DOWN,UP"
                        }
                    }
                }
            }

            function haveChildren(data, list) {
                for (let key in data) {
                    if (typeof data[key] === 'object' && isNaN(data[key].length)) {
                        this.haveChildren(data[key], list)
                    } else {
                        list.push({
                            name: key,
                            value: data[key]
                        })
                    }
                }
                return list
            }
            var mydata = haveChildren(obj, []);
            console.log(mydata1);
        </script>

 

二、在开发的过程中,有接到第二种需求

  表现形式为:

  

 

  代码:

  

<script>
			var obj = {
				eureka1: {
					clinet: {
						clinetclient: 70,
						healthcheck1: {
							enabled: true
						},
						serviceUrl: "http://dsfasdf"
					},
					instance: {
						health: "/health",
						hostname: "${hostname}",
						prefer: true,
						statuspath: "/info"
					},
					server: {
						enabledvation: false,
						peer: 6000
					}
				},
				eureka2: {
					health: {
						status: {
							order: "DOWN,UP"
						}
					}
				}
			}

			function getObjectData(data, list, keyName) {
				for (let key in data) {
					if (keyName) {
						var str = keyName + '.' + key
					} else {
						var str = key;
					}
					if (typeof data[key] === 'object' && isNaN(data[key].length)) {
						this.getObjectData(data[key], list, str)
					} else {
						list.push({
							name: str,
							value: data[key]
						})
					}
				}
				return list
			}

			var mydata1 = getObjectData(obj, []);
			console.log(mydata1);
		</script>

  

 

转载于:https://www.cnblogs.com/blank-longchuan/p/objectTile.html

<think> 我们之前已经详细讨论了JavaScript对象转化的多种方法,包括对象与数组互转、JSON序列化、结构重组以及特殊场景处理等。根据用户提供的参考引用[1],其中强调了对象属性的访问方式(点表示法和方括号表示法)、对象遍历的方法以及一些注意事项(如遍历时使用`hasOwnProperty`检查自身属性)。下面我们将结合这些内容,进一步补充和完善JavaScript对象转化的知识体系。 ### 一、对象属性访问与动态键名 JavaScript中对象属性的访问有两种方式: 1. **点表示法**:`obj.key`,适用于键名是合法标识符且固定已知的情况。 2. **方括号表示法**:`obj[key]`,适用于键名包含特殊字符、动态键名(如拼接字符串)或变量存储键名的情况。 ```javascript const obj = { "first name": "Alice", age: 25 }; // 动态键名示例 const suffix = "name"; console.log(obj["first " + suffix]); // "Alice" [^1] // 变量存储键名 const key = "age"; console.log(obj[key]); // 25 [^1] ``` ### 二、对象遍历与转化结合 遍历对象属性时,常结合转化操作(如过滤、映射)。注意使用`hasOwnProperty`避免遍历到原型链上的属性。 #### 示例:对象属性映射(键名前缀处理) ```javascript const user = { name: "Bob", id: 101 }; // 为每个键名添加前缀 const newUser = {}; for (const key in user) { if (user.hasOwnProperty(key)) { newUser[`user_${key}`] = user[key]; } } // { user_name: "Bob", user_id: 101 } [^1] ``` #### 使用`Object.entries()`更简洁的实现 ```javascript const newUser = Object.fromEntries( Object.entries(user).map(([k, v]) => [`user_${k}`, v]) ); ``` ### 三、对象转化中的类型处理 在JSON转化中,某些JavaScript特有类型(如`Date`, `RegExp`, `Function`)会被特殊处理或丢失: - `JSON.stringify()`遇到`Date`对象会转为ISO字符串。 - `undefined`、函数和Symbol值在转换时会被忽略(在数组中转为`null`)。 #### 自定义JSON序列化(使用`toJSON`方法) 可通过在对象上定义`toJSON`方法自定义序列化行为: ```javascript const obj = { date: new Date(), toJSON() { return { date: this.date.getTime() }; // 转为时间戳 } }; JSON.stringify(obj); // '{"date":1720832487712}' ``` ### 四、复杂嵌对象的转化 对于嵌结构,常需要递归处理。以下是一个深度映射对象键名的函数: ```javascript function deepMapKeys(obj, mapFn) { if (Array.isArray(obj)) { return obj.map(item => deepMapKeys(item, mapFn)); } if (typeof obj === 'object' && obj !== null) { return Object.keys(obj).reduce((acc, key) => { const newKey = mapFn(key); acc[newKey] = deepMapKeys(obj[key], mapFn); return acc; }, {}); } return obj; } // 使用:将键名转为大写 const nested = { a: 1, b: { c: 2 } }; deepMapKeys(nested, k => k.toUpperCase()); // { A:1, B:{ C:2 } } ``` ### 五、特殊对象转化:Map与Object互转 1. **Object转Map** ```javascript const obj = { a: 1, b: 2 }; const map = new Map(Object.entries(obj)); // Map(2) {"a" => 1, "b" => 2} ``` 2. **Map转Object** ```javascript const map = new Map([["x", 10], ["y", 20]]); const obj = Object.fromEntries(map); // {x:10, y:20} ``` ### 六、性能与注意事项 - 避免在循环中频繁使用`JSON.parse()`/`JSON.stringify()`处理大数据,可能引发性能问题。 - 对象克隆时注意深浅拷贝的区别: - 浅拷贝:`Object.assign()`, 扩展运算符`...` - 深拷贝:`JSON.parse(JSON.stringify(obj))`(有局限)或使用工具库(如lodash的`_.cloneDeep`) --- ### 相关问题 1. 如何正确处理JSON序列化中的循环引用? 2. 对象键名映射时如何避免修改原型链上的属性? 3. Map对象和普通对象在存取机制上有何本质区别? 4. 如何实现一个支持自定义类型处理的深拷贝函数? 以上内容整合了基础转化方法和高级技巧,并强调了实际开发中的常见痛点及解决方案。 [^1] </think> ### JavaScript对象(Object)转化方法详解(补充版) 基于引用[1]的核心知识点,结合对象属性访问、遍历机制和转化逻辑,系统梳理如下: --- #### 一、对象属性本质与访问机制 1. **属性名的实质** - 点表示法 `obj.name` 等价于方括号表示法 `obj["name"]` - 动态属性名可通过拼接实现: ```javascript const num = 1; obj['key' + num] = 'value'; // obj.key1 = 'value' [^1] ``` 2. **in运算符检测属性** ```javascript console.log("name" in obj); // 检测属性是否存在(含原型链)[^1] ``` --- #### 二、对象遍历与转化结合实践 1. **正确遍历属性值** ```javascript // 错误方式:obj.prop 会查找名为"prop"的属性 for (let prop in obj) { console.log(obj.prop) } // ❌ 输出 undefined // 正确方式:使用方括号动态访问 for (let prop in obj) { console.log(obj[prop]) } // ✅ 输出值 [^1] ``` 2. **过滤原型链属性** ```javascript for (let prop in obj) { if (obj.hasOwnProperty(prop)) { // 仅操作自身属性 console.log(`${prop}: ${obj[prop]}`); } } [^1] ``` --- #### 三、对象⇋数组互转(强化版) 1. **动态键值重组** ```javascript const data = { user_age: 25, user_name: "Alice" }; // 移除键名前缀 const cleanData = Object.fromEntries( Object.entries(data).map(([key, val]) => [ key.replace("user_", ""), val ]) ); // { age:25, name:"Alice" } ``` 2. **多维结构转化** ```javascript const matrix = { row1: ["A1", "A2"], row2: ["B1", "B2"] }; // 对象→二维数组 const arr2D = Object.values(matrix); // [ ["A1","A2"], ["B1","B2"] ] ``` --- #### 四、JSON转化深度处理 1. **自定义序列化逻辑** ```javascript const customObj = { date: new Date(), toJSON: function() { return { timestamp: this.date.getTime() } } }; JSON.stringify(customObj); // '{"timestamp":1720832487712}' ``` 2. **解析数据格式化** ```javascript const jsonStr = '{"date":"2023-07-15T12:00:00Z"}'; const result = JSON.parse(jsonStr, (key, val) => key === "date" ? new Date(val) : val ); console.log(result.date instanceof Date); // true ``` --- #### 五、特殊场景解决方案 1. **避免循环引用报错** ```javascript const circularRefCache = new WeakSet(); const safeStringify = (obj) => { if (typeof obj !== 'object' || obj === null) return obj; if (circularRefCache.has(obj)) return '[Circular]'; circularRefCache.add(obj); // ...递归处理 }; ``` 2. **类数组对象转化** ```javascript // Arguments对象→数组 function demo() { return Array.from(arguments); } demo(1, 2); // [1, 2] ``` --- ### 综合示例:动态表单数据处理 ```javascript // 原始表单数据(含动态生成的字段) const formData = { "item_1": "Apple", "item_2": "Orange", "meta": { user: "Bob", timestamp: Date.now() } }; // 步骤1:平铺对象 const flattened = Object.entries(formData).flatMap(([k, v]) => typeof v === 'object' ? Object.entries(v).map(([subk, subv]) => [`${k}.${subk}`, subv]) : [[k, v]] ); // 步骤2:重组为规范结构 const normalized = Object.fromEntries(flattened); /* 输出: { "item_1": "Apple", "item_2": "Orange", "meta.user": "Bob", "meta.timestamp": 1720832487712 } */ ``` --- ### 相关问题 1. 如何实现对象深拷贝并处理循环引用? 2. `Object.entries()`与`for...in`遍历的性能差异是什么? 3. JSON序列化时如何保留`undefined`类型? 4. 怎样将Map类型数据转化为带类型标记的JSON? [^1]: 对象属性访问机制与遍历安全实践
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值