当先锋百科网

首页 1 2 3 4 5 6 7

1、JSON对象

在学习之前,我们先来看下JSON对象。早期的JSON解析器基本上就是使用JavaScript的eval()函数。由于JSON是JavaScript语法的子集,因此eval()函数可以解析,解释并释放JavaScript对象和数组。在此,对于eval()函数的具体用法和解释,我们本次不做具体的分析。

我们本次来看下面两个JSON对象的方法:

  • stringify()把javaScript对象序列化为JSON字符串
  • parse()把JSON字符串解析为原生JavaScript值。
例如,我们创建了一个关于书本的信息的js对象:
var book = {
    title:"Professional JavaScript",
    author:["Dave"],
    edition:3,
    year:2015
};
var jsonText = JSON.stringify(book); //把js对象序列化为了json字符串
console.log(jsonText);
我们在浏览器中打开console面板,会看到如下信息:

我们在同样的,将刚才已经序列化好的json对象的变量拿过来,使用parse()方法将其在转化为js值
var bookCopy = JSON.parse(jsonText);//把json字符串转化为js值
然后,再次打开浏览器console面板,会看到如下信息:

至此,JSON的两个方法stringify()和parse()的基本使用已经介绍完了。下面我们来介绍下这两个方法其他的用法和理解。

2.序列化选项JSON.stringify()

实际上,JSON.stringify()除了接收要序列化的JavaScript对象外,还可以接收另外两个参数,这两个参数用于指定以不同的方式序列化JavaScript对象。

  • 过滤器参数,可以是一个数组,也可以是一个函数。
  • 选项参数,表示是否在JSON字符串中保留缩进。
我们 先来看过滤器参数:
2.1过滤结果
如果过滤器参数是数组,那么JSON.stringify()的结果将只包含数组中列出的属性。
我们使用前面定义的book变量,来做个例子:

var jsonText = JSON.stringify(book, ["title", "edition"]);

这里我们在序列化book对象的时候,给出了一个数组参数,其中包含两个字符串:"title"和"edition"。这两个属性与将要序列化的对象中的属性是对应的,因此在返回的结果字符串中,我们会看到只包含"title"和"edition"两个属性的信息:

另外,我们再来讨论该参数为函数的时候。

传入的函数接收两个参数,属性(键)名和属性值。其中,属性名只能是字符串,而在值非键值对结构的 值时,键名可以是空字符串。为了改变序列化对象的结果,函数返回的值就是相应的值,不过,如果函数返回了undefined,那么相应的属性会被忽略。
我们来看个例子
//在此我们依旧调用了前面定义的book变量
var jsonText = JSON.stringify(book, function(key, value){
    switch(key){
<span style="white-space:pre">	</span>//如果键为author,就将数组连接为一个字符串
        case "author":
            return value.join(",")
<span style="white-space:pre">	</span>//如果键为year,就将其值设为5000
        case "year":
            return 5000;
<span style="white-space:pre">	</span>//如果值为edition,就通过返回undefined删除该属性
        case "edition":
            return undefined;
<span style="white-space:pre">	</span>//使用default,此时返回传入的值,即其他键值对保持默认不变
        default:
            return value;
    }
})
我们来查看下浏览器console面板中打印的结果:
//使用了函数作为第二个参数
为了更好的观察,我们把前面没有使函数作为第二个参数的返回结果拿过来: //没有使用了函数作为第二个参数
我们会发现,author的值变成了"Dave"字符串,year的值也变成了5000,editio属性则消失了。
注意:Firefox3.5 和3.6对JSON.stringify()的实现有一个bug,即在使用将函数作为第二个参数的时候。对此我们不做深入。此bug在Firefox4中已经得到解决。
2.2字符串缩进

JSON.stringify()方法的第三个参数用于控制结果中的缩进和空白符。如果这个参数是一个数值,那它表示的每个级别缩进的空格数。我们接着来看例子:
//再次,我们依旧使用了前面定义过的book变量,并且使用stringify()方法对其序列化,注意,此处我们没有使用过滤器,即第二个参数
var jsonText = JSON.stringify(book,null,4)//4即表示每个级别要缩进四个空格
我们来看下在浏览器consol面板中打印的结果:

为了更好的理解和观察,我用红色矩形区域将每行的空格给标记了出来,我们会发现,每行都缩进了4个空格,同样我们将参数4改为10,其缩进的距离会更大。
我们需要注意和理解的是,最大缩进空格数为10,所有大于10的值都会自动转换为10。当然,缩进参数我们也可以使用一个字符串,这个字符串会被用作缩进字符。
//我们将4改为"- -"
var jsonText = JSON.stringify(book,null,"- -")
结果:

我们会明显的发现,空格变成了我们我们传递的 那个字符串参数。同样的,如果字符串长度超过了10,结果中将只会显示先10个字符
2.3、toJSON()方法
有时候,JSON.stringify()还是不能满足对某些对象进行自定义序列化的需求。我们可以使用toJSON()方法,返回其自身的JSON数据格式。我们来看个例子:
//在此我们重新定义个book变量
var book = {
    title:"Professional JavaScript",
    author:["Dave"],
    edition:3,
    year:2015,
    //使用toJSON()方法,返回该对象的title
    toJSON:function(){
        return this.title;
    }
}
var jsonText = JSON.stringify(book);
结果:

我们会发现,该方法只返回了title;

2.解析选项JSON.parse()

JSON.parse()方法也可以接收另外一个参数,该参数是一个函数,将在每个键值对上调用。我们称之为还原函数。

如果还原函数返回undefined,则表示要从结果中删除相应的键;如果返回其他值,则将该值插入到结果中。在将日期字符串转换为Date对象时,经常要用到还原函数。我们依旧来看个例子:

//我们又一次重新定义了book变量
var book = {
     title:"Professional JavaScript",
    author:["Dave"],
    edition:3,
    year:2015,
    releaseDate:new Date(2011,11,1)
}
//先将其序列化为JSON字符串
var jsonText = JSON.stringify(book);
//在对jsonText进行pase方法的转换
var bookCopy = JSON.parse(jsonText, function(key, value){
    if(key == "releaseDate"){
        return new Date(value);
    }else{
        return value;
    }
})
结果:


我们会发现,返回的releaseDate是一个Date对象,当我们不使用还原函数,再来看下返回的结果:


我们会发现,返回的releaseDate的值是一个字符串。

我们知道,字符串是无法调用Date对象的getFullYear()等方法的,而只有我们使用了还原函数,使其变成了Date对象后,我们就可以使用Date对象的getFullYear()等方法了。

吐舌头吐舌头