怎么做网站的轮播图,设计坞官网首页,东莞企石做网站,微网站设计制作第十一节 JSON对象
1. JSON 格式
JSON 格式#xff08;JavaScript Object Notation 的缩写#xff09;是一种用于数据交换的文本格式#xff0c;2001年由 Douglas Crockford 提出#xff0c;目的是取代繁琐笨重的 XML 格式。
相比 XML 格式#xff0c;JSON 格式有两个显…第十一节 JSON对象
1. JSON 格式
JSON 格式JavaScript Object Notation 的缩写是一种用于数据交换的文本格式2001年由 Douglas Crockford 提出目的是取代繁琐笨重的 XML 格式。
相比 XML 格式JSON 格式有两个显著的优点书写简单一目了然符合 JavaScript 原生语法可以由解释引擎直接处理不用另外添加解析代码。所以JSON 迅速被接受已经成为各大网站交换数据的标准格式并被写入标准。
每个 JSON 对象就是一个值可能是一个数组或对象也可能是一个原始类型的值。总之只能是一个值不能是两个或更多的值。
JSON 对值的类型和格式有严格的规定。
复合类型的值只能是数组或对象不能是函数、正则表达式对象、日期对象。原始类型的值只有四种字符串、数值必须以十进制表示、布尔值和null不能使用NaN, Infinity, -Infinity和undefined。字符串必须使用双引号表示不能使用单引号。对象的键名必须放在双引号里面。数组或对象最后一个成员的后面不能加逗号。
以下都是合法的 JSON。
[one, two, three]{ one: 1, two: 2, three: 3 }{names: [张三, 李四] }[ { name: 张三}, {name: 李四} ]
以下都是不合法的 JSON。
{ name: 张三, age: 32 } // 属性名必须使用双引号[32, 64, 128, 0xFFF] // 不能使用十六进制值{ name: 张三, age: undefined } // 不能使用 undefined{ name: 张三,birthday: new Date(Fri, 26 Aug 2011 07:13:10 GMT),getName: function () {return this.name;}
} // 属性值不能使用函数和日期对象
注意null、空数组和空对象都是合法的 JSON 值。
2. JSON 对象
JSON对象是 JavaScript 的原生对象用来处理 JSON 格式数据。它有两个静态方法JSON.stringify()和JSON.parse()。
3. JSON.stringify()
3.1 基本用法
JSON.stringify()方法用于将一个值转为 JSON 字符串。该字符串符合 JSON 格式并且可以被JSON.parse()方法还原。
JSON.stringify(abc) // abc
JSON.stringify(1) // 1
JSON.stringify(false) // false
JSON.stringify([]) // []
JSON.stringify({}) // {}JSON.stringify([1, false, false])
// [1,false,false]JSON.stringify({ name: 张三 })
// {name:张三}
上面代码将各种类型的值转成 JSON 字符串。
注意对于原始类型的字符串转换结果会带双引号。
JSON.stringify(foo) foo // false
JSON.stringify(foo) \foo\ // true
上面代码中字符串foo被转成了\foo\。这是因为将来还原的时候内层双引号可以让 JavaScript 引擎知道这是一个字符串而不是其他类型的值。
JSON.stringify(false) // false
JSON.stringify(false) // \false\
上面代码中如果不是内层的双引号将来还原的时候引擎就无法知道原始值是布尔值还是字符串。
如果对象的属性是undefined、函数或 XML 对象该属性会被JSON.stringify()过滤。
var obj {a: undefined,b: function () {}
};JSON.stringify(obj) // {}
上面代码中对象obj的a属性是undefined而b属性是一个函数结果都被JSON.stringify过滤。
如果数组的成员是undefined、函数或 XML 对象则这些值被转成null。
var obj {a: undefined,b: function () {}
};JSON.stringify(obj) // {}
上面代码中数组arr的成员是undefined和函数它们都被转成了null。
正则对象会被转成空对象。
JSON.stringify(/foo/) // {}
JSON.stringify()方法会忽略对象的不可遍历的属性。
var obj {};
Object.defineProperties(obj, {foo: {value: 1,enumerable: true},bar: {value: 2,enumerable: false}
});JSON.stringify(obj); // {foo:1}
上面代码中bar是obj对象的不可遍历属性JSON.stringify方法会忽略这个属性。
3.2 第二个参数
JSON.stringify()方法还可以接受一个数组作为第二个参数指定参数对象的哪些属性需要转成字符串。
var obj {prop1: value1,prop2: value2,prop3: value3
};var selectedProperties [prop1, prop2];JSON.stringify(obj, selectedProperties)
// {prop1:value1,prop2:value2}
上面代码中JSON.stringify()方法的第二个参数指定只转prop1和prop2两个属性。
这个类似白名单的数组只对对象的属性有效对数组无效。
JSON.stringify([a, b], [0])
// [a,b]JSON.stringify({0: a, 1: b}, [0])
// {0:a}
上面代码中第二个参数指定 JSON 格式只转0号属性实际上对数组是无效的只对对象有效。
第二个参数还可以是一个函数用来更改JSON.stringify()的返回值。
function f(key, value) {if (typeof value number) {value 2 * value;}return value;
}JSON.stringify({ a: 1, b: 2 }, f)
// {a: 2,b: 4}
上面代码中的f函数接受两个参数分别是被转换的对象的键名和键值。如果键值是数值就将它乘以2否则就原样返回。
注意这个处理函数是递归处理所有的键。
var obj {a: {b: 1}};function f(key, value) {console.log([ key ]: value);return value;
}JSON.stringify(obj, f)
// []:[object Object]
// [a]:[object Object]
// [b]:1
// {a:{b:1}}
上面代码中对象obj一共会被f函数处理三次输出的最后那行是JSON.stringify()的默认输出。第一次键名为空键值是整个对象obj第二次键名为a键值是{b: 1}第三次键名为b键值为1。
递归处理中每一次处理的对象都是前一次返回的值。
var obj {a: 1};function f(key, value) {if (typeof value object) {return {b: 2};}return value * 2;
}JSON.stringify(obj, f)
// {b: 4}
上面代码中f函数修改了对象obj接着JSON.stringify()方法就递归处理修改后的对象obj。
如果处理函数返回undefined或没有返回值则该属性会被忽略。
function f(key, value) {if (typeof(value) string) {return undefined;}return value;
}JSON.stringify({ a: abc, b: 123 }, f)
// {b: 123}
上面代码中a属性经过处理后返回undefined于是该属性被忽略了。
3.3 第三个参数
JSON.stringify()还可以接受第三个参数用于增加返回的 JSON 字符串的可读性。
默认返回的是单行字符串对于大型的 JSON 对象可读性非常差。第三个参数使得每个属性单独占据一行并且将每个属性前面添加指定的前缀不超过10个字符。
// 默认输出
JSON.stringify({ p1: 1, p2: 2 })
// JSON.stringify({ p1: 1, p2: 2 })// 分行输出
JSON.stringify({ p1: 1, p2: 2 }, null, \t)
// {
// p1: 1,
// p2: 2
// }
上面例子中第三个属性\t在每个属性前面添加一个制表符然后分行显示。
第三个属性如果是一个数字则表示每个属性前面添加的空格最多不超过10个。
JSON.stringify({ p1: 1, p2: 2 }, null, 2);
/*
{p1: 1,p2: 2
}
*/
3.4 参数对象的 toJSON() 方法
如果参数对象有自定义的toJSON()方法那么JSON.stringify()会使用这个方法的返回值作为参数而忽略原对象的其他属性。
下面是一个普通的对象。
var user {firstName: 三,lastName: 张,get fullName(){return this.lastName this.firstName;}
};JSON.stringify(user)
// {firstName:三,lastName:张,fullName:张三}
现在为这个对象加上toJSON()方法。
var user {firstName: 三,lastName: 张,get fullName(){return this.lastName this.firstName;},toJSON: function () {return {name: this.lastName this.firstName};}
};JSON.stringify(user)
// {name:张三}
上面代码中JSON.stringify()发现参数对象有toJSON()方法就直接使用这个方法的返回值作为参数而忽略原对象的其他参数。
Date对象就有一个自己的toJSON()方法。
var date new Date(2015-01-01);
date.toJSON() // 2015-01-01T00:00:00.000Z
JSON.stringify(date) // 2015-01-01T00:00:00.000Z
上面代码中JSON.stringify()发现处理的是Date对象实例就会调用这个实例对象的toJSON()方法将该方法的返回值作为参数。
toJSON()方法的一个应用是将正则对象自动转为字符串。因为JSON.stringify()默认不能转换正则对象但是设置了toJSON()方法以后就可以转换正则对象了。
var obj {reg: /foo/
};// 不设置 toJSON 方法时
JSON.stringify(obj) // {reg:{}}// 设置 toJSON 方法时
RegExp.prototype.toJSON RegExp.prototype.toString;
JSON.stringify(/foo/) // /foo/
上面代码在正则对象的原型上面部署了toJSON()方法将其指向toString()方法因此转换成 JSON 格式时正则对象就先调用toJSON()方法转为字符串然后再被JSON.stringify()方法处理。
4. JSON.parse()
JSON.parse()方法用于将 JSON 字符串转换成对应的值。
JSON.parse({}) // {}
JSON.parse(true) // true
JSON.parse(foo) // foo
JSON.parse([1, 5, false]) // [1, 5, false]
JSON.parse(null) // nullvar o JSON.parse({name: 张三});
o.name // 张三
如果传入的字符串不是有效的 JSON 格式JSON.parse()方法将报错。
JSON.parse(String) // illegal single quotes
// SyntaxError: Unexpected token ILLEGAL
上面代码中双引号字符串中是一个单引号字符串因为单引号字符串不符合 JSON 格式所以报错。
为了处理解析错误可以将JSON.parse()方法放在try...catch代码块中。
try {JSON.parse(String);
} catch(e) {console.log(parsing error);
}
JSON.parse()方法可以接受一个处理函数作为第二个参数用法与JSON.stringify()方法类似。
function f(key, value) {if (key a) {return value 10;}return value;
}JSON.parse({a: 1, b: 2}, f)
// {a: 11, b: 2}
上面代码中JSON.parse()的第二个参数是一个函数如果键名是a该函数会将键值加上10。
JSON.parse()和JSON.stringify()可以结合使用像下面这样写实现对象的深拷贝。
JSON.parse(JSON.stringify(obj))
上面这种写法可以深度克隆一个对象但是对象内部不能有 JSON
不允许的数据类型比如函数、正则对象、日期对象等。