var friend={ "firstName": "Good", "lastName": "Man", "phone":"1234567", "age":18 }; var friendAfter=JSON.stringify(friend,function(key,value){ if(key==="phone") return "(000)"+value; else if(typeof value === "number") return value + 10; else return value; //如果你把这个else分句删除,那么结果会是undefined }); console.log(friendAfter); //输出:{"firstName":"Good","lastName":"Man","phone":"(000)1234567","age":28}
如果制定了第二个参数是函数,那么这个函数必须对每一项都有返回,这个函数接受两个参数,一个键名,一个是属性值,函数必须针对每一个原来的属性值都要有新属性值的返回。
那么问题来了,如果传入的不是键值对的对象形式,而是方括号的数组形式呢?,比如上面的friend变成这样:friend=["Jack","Rose"],那么这个逐属性处理的函数接收到的key和value又是什么?如果是数组形式,那么key是索引,而value是这个数组项,你可以在控制台在这个函数内部打印出来这个key和value验证。
这第二个参数若是数组
var friend={ "firstName": "Good", "lastName": "Man", "phone":"1234567", "age":18 }; //注意下面的数组有一个值并不是上面对象的任何一个属性名 var friendAfter=JSON.stringify(friend,["firstName","address","phone"]); console.log(friendAfter); //{"firstName":"Good","phone":"1234567"} //指定的“address”由于没有在原来的对象中找到而被忽略
如果第二个参数是一个数组,那么只有在数组中出现的属性才会被序列化进结果字符串,只要在这个提供的数组中找不到的属性就不会被包含进去,而这个数组中存在但是源JS对象中不存在的属性会被忽略,不会报错。
1.3 第三个参数用于美化输出——不建议用
指定缩进用的空白字符,可以取以下几个值:
是1-10的某个数字,代表用几个空白字符
是字符串的话,就用该字符串代替空格,最多取这个字符串的前10个字符
没有提供该参数 等于 设置成null 等于 设置一个小于1的数
var friend={ "firstName": "Good", "lastName": "Man", "phone":{"home":"1234567","work":"7654321"} }; //直接转化是这样的: //{"firstName":"Good","lastName":"Man","phone":{"home":"1234567","work":"7654321"}} var friendAfter=JSON.stringify(friend,null,4); console.log(friendAfter); /* { "firstName": "Good", "lastName": "Man", "phone": { "home": "1234567", "work": "7654321" } } */ var friendAfter=JSON.stringify(friend,null,"HAHAHAHA"); console.log(friendAfter); /* { HAHAHAHA"firstName": "Good", HAHAHAHA"lastName": "Man", HAHAHAHA"phone": { HAHAHAHAHAHAHAHA"home": "1234567", HAHAHAHAHAHAHAHA"work": "7654321" HAHAHAHA} } */ var friendAfter=JSON.stringify(friend,null,"WhatAreYouDoingNow"); console.log(friendAfter); /* 最多只取10个字符 { WhatAreYou"firstName": "Good", WhatAreYou"lastName": "Man", WhatAreYou"phone": { WhatAreYouWhatAreYou"home": "1234567", WhatAreYouWhatAreYou"work": "7654321" WhatAreYou} } */
笑笑就好,别这样用,序列化是为了传输,传输就是能越小越好,加莫名其妙的缩进符,解析困难(如果是字符串的话),也弱化了轻量化这个特点。
1.4 注意这个函数的“小聪明”(重要)
如果有其他不确定的情况,那么最好的办法就是"Have a try",控制台做下实验就明了。
键名不是双引号的(包括没有引号或者是单引号),会自动变成双引号;字符串是单引号的,会自动变成双引号
最后一个属性后面有逗号的,会被自动去掉
非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中
这个好理解,也就是对非数组对象在最终字符串中不保证属性顺序和原来一致
布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值
也就是你的什么new String("bala")会变成"bala",new Number(2017)会变成2017
undefined、任意的函数(其实有个函数会发生神奇的事,后面会说)以及 symbol 值(symbol详见ES6对symbol的介绍)
出现在非数组对象的属性值中:在序列化过程中会被忽略
出现在数组中时:被转换成 null