Maison >interface Web >js tutoriel >Explication détaillée des compétences d'utilisation de JSON dans JS

Explication détaillée des compétences d'utilisation de JSON dans JS

php中世界最好的语言
php中世界最好的语言original
2018-05-17 14:37:192490parcourir

Cette fois, je vais vous donner une explication détaillée des techniques d'utilisation de JSON en JS. Quelles sont les précautions lors de l'utilisation de JSON en JS. Voici des cas pratiques, jetons un coup d'œil.

Examinons d'abord une sérialisation d'objet JS courante dans un problème de chaîne JSON. À quoi ressemble la chaîne de l'objet JS suivant après avoir passé JSON.stringify ? Ne vous précipitez pas pour le copier et le coller dans la console. Ouvrez d'abord un éditeur de code ou un papier, écrivez et lisez, puis comparez soigneusement la sortie de votre console après l'écriture. Si vous faites des erreurs, n'oubliez pas de lire l'intégralité du texte et de commenter. haha.

var friend={ 
  firstName: 'Good',
  'lastName': 'Man',
  'address': undefined,
  'phone': ["1234567",undefined],
  'fullName': function(){
    return this.firstName + ' ' + this.lastName;
  }
};

JSON.stringify(friend);//这一行返回什么呢?

La deuxième question est la suivante : si je veux changer le nom de « l'ami » en lettres majuscules dans la chaîne JSON finale, c'est-à-dire changer « Good » en « GOOD » et « Man » " "Devient "HOMME", alors que faire ?

Sur la base des deux questions ci-dessus, revenons à la source et demandons-nous : qu'est-ce que JSON exactement ? Pourquoi JSON est-il facile d'échanger des données ? Quelle est la différence entre les objets JSON et JS ? En JS, JSON.parse, JSON.stringify et les rares toJSON, quels sont les paramètres et les détails de traitement de ces fonctions ?

Bienvenue dans ce "JSON Deep Journey". Ci-dessous, nous comprendrons JSON sous les aspects suivants :

  • Tout d'abord, nous discuterons de "JSON est un poids léger". Compréhension du "format d'échange de données quantitatives" ;

  • Regardons ensuite la différence entre les objets JSON et JS qui sont souvent confondus

  • Enfin ; Revenons sur les détails d'exécution spécifiques de ces fonctions liées à JSON dans JS.

J'espère que le texte intégral aidera les gens comme moi qui connaissent peu JSON à pouvoir expliquer clairement ce qu'est JSON, à pouvoir utiliser JSON avec compétence et à savoir comment sérialisez les objets JS en JSON sans regarder la console Quelle est la sortie après la chaîne.

1. JSON est un format, basé sur du texte, mieux que léger, utilisé pour échanger des données

Si vous n'avez pas assisté à l'introduction officielle de JSON, vous pouvez aller ici, les premier et deuxième paragraphes de l'introduction officielle ont clairement indiqué ce qu'est JSON. J'ai affiné ce qu'est JSON dans les aspects suivants :

1. >Qu'est-ce que le format ? Il s'agit de standardiser la façon dont vos données doivent être exprimées. Par exemple, il y a une personne nommée « Deux cent six », mesurant « 160 cm » et pesant « 60 kg ». Vous souhaitez maintenant transmettre les informations de cette personne à d'autres. ou autre chose. Vous avez plusieurs choix :

    Nom "deux cent six", taille "160cm", poids "60kg"
  • nom. ="二Cent six"&hauteur="160cm"&poids="60kg"
  • 0b0e84076f28323414dd9fb8eb7975feac64eef71da29b3103d7dea589cbf495deux cent six0f18ffde598092fae58470f834f2c729b22cfe395b70b587bd9ee4e59fb135a51600224c2d70b22401bb3754088898ae895 2171260e3bb1719fd145aef85e0a6db2605dc7adf5afe662fc39c0e6d73d08c801ab999d0dfe3b51d550c7fce222809fe1
  • {"name": "二百六", "hauteur": 160, "poids": 60}
  • ... ...
  • Pour toutes les options ci-dessus, les données transmises sont les mêmes, mais vous pouvez voir que le format peut être différent Divers, il s'agit de données formatées diverses, JSON est l'une des méthodes de représentation.

2. Format de données basé sur du texte

JSON est un format de données basé sur du texte, par opposition aux données binaires, donc lorsque JSON est transmis, il est conforme en JSON Les chaînes dans ce format (nous parlerons du format du JSON dans la deuxième partie) sont souvent appelées « chaînes JSON ».

3. Format de données léger

Avant JSON, il existait un format de données appelé XML, qui est encore largement utilisé, mais JSON est plus léger, comme XML l'exige. beaucoup de balises. Comme dans l'exemple ci-dessus, vous pouvez clairement voir que les balises elles-mêmes occupent beaucoup d'espace dans les données au format XML, tandis que JSON est relativement léger, c'est-à-dire que les mêmes données au format JSON occupent moins de bande passante. présente des avantages évidents lorsqu’une grande quantité de données est demandée et transférée.

4. Largement utilisé pour l'échange de données

La légèreté est déjà un avantage pour l'échange de données, mais plus important encore, JSON est facile à lire et à écrire et analysé par machine, c'est-à-dire que ce JSON est convivial à la fois pour les humains et les machines, et est léger et indépendant du langage (car il est basé sur du texte), de sorte que JSON est largement utilisé pour l'échange de données.

Par exemple, Requête POST pour ajax avec JS front-end, et requête de traitement PHP back-end par exemple :

  1. Le front-end construit un Objet JS pour envelopper la requête Les données transmises sont ensuite converties en une chaîne JSON, puis la requête est envoyée au backend

  2. Le backend PHP reçoit cette chaîne JSON et convertit le JSON ; chaîne dans un objet PHP, puis gérez la requête.

Comme vous pouvez le constater, les mêmes données ont ici trois manifestations différentes, à savoir les objets JS front-end, les chaînes JSON transmises, les objets PHP back-end, les objets JS et les objets PHP sont évidemment ce n'est pas la même chose, mais comme tout le monde utilise JSON pour transmettre des données, tout le monde peut comprendre ce format de données et peut facilement convertir le format de données JSON en une structure de données qu'il peut comprendre. C'est pratique, il en va de même pour l'échange de données dans divers autres. environnements linguistiques.

2. "Gossip" entre les objets JSON et JS

J'entends souvent l'expression "JSON est un sous-ensemble de JS", et ceci En d'autres termes, j'ai J'ai toujours cru que chaque chaîne conforme au format JSON pouvait être analysée en js, ​​jusqu'à ce que je découvre plus tard une chose étrange...

1 Pourquoi deux choses essentiellement différentes sont-elles si proches ? 🎜>

Les objets JSON et JS sont essentiellement la même chose, tout comme "zebra crossing" et "zebra", "zebra crossing" est basé sur les rayures sur "zebra" pour présenter et nommer, mais les zèbres sont les passages piétons vivants et piétons sont des êtres non vivants.

De même, le nom complet de "JSON" est "

JavaScript Object Notation", donc son format (syntaxe) est basé sur JS, mais c'est un format, et l'objet JS est une instance est quelque chose qui existe en mémoire.

Je plaisante, si JSON était basé sur PHP, il pourrait s'appeler PON, et le formulaire pourrait ressembler à ceci ['propertyOne' => 'foo', 'propertyTwo' => si tel est le cas, alors JSON est peut-être désormais plus proche de PHP.

De plus, JSON peut être transmis car il est au format texte, mais les objets JS ne peuvent pas être transmis syntaxiquement, JSON sera plus strict, mais les objets JS sont très lâches.

Alors pourquoi deux choses différentes sont-elles si proches ? Parce qu'après tout, JSON a évolué à partir de JS et a une syntaxe similaire ?

2. Quelle est la syntaxe stricte du format JSON par rapport à l'objet JS

Comparons d'abord les deux sous la forme de « paires clé-valeur en tant qu'objets représentés ? « Les différences, quant à la façon dont JSON peut être exprimé, seront répertoriées après comparaison.

Comparer le contenu JSON Objet JS
Le nom de la clé
对比内容 JSON JS对象

键名

必须是加双引号

可允许不加、加单引号、加双引号

属性值

只能是数值(10进制)、字符串(双引号)、布尔值和null,
     也可以是数组或者符合JSON要求的对象,
     不能是函数、NaN, Infinity, -Infinity和undefined

爱啥啥

逗号问题

最后一个属性后面不能有逗号

可以

数值

前导0不能用,小数点后必须有数字

没限制

doit être placé entre guillemets doubles peut être omis , ajoutez des guillemets simples, ajoutez des guillemets doubles
La valeur de l'attribut ne peut être qu'une valeur numérique ( système base 10), chaîne (guillemets doubles), booléen et nul,
Il peut également s'agir d'un tableau ou d'un objet répondant aux exigences JSON,
Il ne peut pas s'agir d'une fonction, NaN, Infinity, -Infinity et undefined
Aishasha
Problème de virgule Il ne peut pas y avoir de virgule après le dernier attribut Oui
Valeur Le 0 initial ne peut pas être utilisé, il doit y avoir des chiffres après la virgule décimale Aucune limite

 可以看到,相对于JS对象,JSON的格式更严格,所以大部分写的JS对象是不符合JSON的格式的。

以下代码引用自这里
var obj1 = {}; // 这只是 JS 对象

// 可把这个称做:JSON 格式的 JavaScript 对象 
var obj2 = {"width":100,"height":200,"name":"rose"};

// 可把这个称做:JSON 格式的字符串
var str1 = '{"width":100,"height":200,"name":"rose"}';

// 这个可叫 JSON 格式的数组,是 JSON 的稍复杂一点的形式
var arr = [ 
  {"width":100,"height":200,"name":"rose"},
  {"width":100,"height":200,"name":"rose"},
  {"width":100,"height":200,"name":"rose"},
];

// 这个可叫稍复杂一点的 JSON 格式的字符串   
var str2='['+ 
  '{"width":100,"height":200,"name":"rose"},'+
  '{"width":100,"height":200,"name":"rose"},'+
  '{"width":100,"height":200,"name":"rose"},'+
']';

另外,除了常见的“正常的”JSON格式,要么表现为一个对象形式{...},要么表现为一个数组形式[...],任何单独的一个10进制数值、双引号字符串、布尔值和null都是有效符合JSON格式的。

这里有完整的JSON语法参考

3. 一个有意思的地方,JSON不是JS的子集

首先看下面的代码,你可以copy到控制台执行下:

var code = '"\u2028\u2029"'; 
JSON.parse(code); // works fine 
eval(code); // fails

这两个字符\u2028和\u2029分别表示行分隔符和段落分隔符,JSON.parse可以正常解析,但是当做js解析时会报错。

三、这几个JS中的JSON函数,弄啥嘞

在JS中我们主要会接触到两个和JSON相关的函数,分别用于JSON字符串和JS数据结构之间的转化,一个叫JSON.stringify,它很聪明,聪明到你写的不符合JSON格式的JS对象都能帮你处理成符合JSON格式的字符串,所以你得知道它到底干了什么,免得它只是自作聪明,然后让你Debug long time;另一个叫JSON.parse,用于转化json字符串到JS数据结构,它很严格,你的JSON字符串如果构造地不对,是没办法解析的。

而它们的参数不止一个,虽然我们经常用的时候只传入一个参数。

此外,还有一个toJSON函数,我们较少看到,但是它会影响JSON.stringify

1. 将JS数据结构转化为JSON字符串——JSON.stringify

这个函数的函数签名是这样的:

JSON.stringify(value[, replacer [, space]])

下面将分别展开带1~3个参数的用法,最后是它在序列化时做的一些“聪明”的事,要特别注意。

1.1 基本使用——仅需一个参数
这个大家都会使用,传入一个JSON格式的JS对象或者数组,JSON.stringify({"name":"Good Man","age":18})返回一个字符串"{"name":"Good Man","age":18}"

可以看到本身我们传入的这个JS对象就是符合JSON格式的,用的双引号,也没有JSON不接受的属性值,那么如果像开头那个例子中的一样,how to play?不急,我们先举简单的例子来说明这个函数的几个参数的意义,再来说这个问题。

1.2 第二个参数可以是函数,也可以是一个数组

  • 如果第二个参数是一个函数,那么序列化过程中的每个属性都会被这个函数转化和处理

  • 如果第二个参数是一个数组,那么只有包含在这个数组中的属性才会被序列化到最终的JSON字符串中

  • 如果第二个参数是null,那作用上和空着没啥区别,但是不想设置第二个参数,只是想设置第三个参数的时候,就可以设置第二个参数为null

这第二个参数若是函数

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

JSON.stringify({x: undefined, y: function(){return 1;}, z: Symbol("")}); 
//出现在非数组对象的属性值中被忽略:"{}"
JSON.stringify([undefined, Object, Symbol("")]); 
//出现在数组对象的属性值中,变成null:"[null,null,null]"

NaN、Infinity和-Infinity,不论在数组还是非数组的对象中,都被转化为null

所有以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们

不可枚举的属性会被忽略

2. 将JSON字符串解析为JS数据结构——JSON.parse

这个函数的函数签名是这样的:

JSON.parse(text[, reviver])

如果第一个参数,即JSON字符串不是合法的字符串的话,那么这个函数会抛出错误,所以如果你在写一个后端返回JSON字符串的脚本,最好调用语言本身的JSON字符串相关序列化函数,而如果是自己去拼接实现的序列化字符串,那么就尤其要注意序列化后的字符串是否是合法的,合法指这个JSON字符串完全符合JSON要求的严格格式

值得注意的是这里有一个可选的第二个参数,这个参数必须是一个函数,这个函数作用在属性已经被解析但是还没返回前,将属性处理后再返回。

var friend={ 
  "firstName": "Good",
  "lastName": "Man",
  "phone":{"home":"1234567","work":["7654321","999000"]}
};

//我们先将其序列化
var friendAfter=JSON.stringify(friend); 
//'{"firstName":"Good","lastName":"Man","phone":{"home":"1234567","work":["7654321","999000"]}}'

//再将其解析出来,在第二个参数的函数中打印出key和value
JSON.parse(friendAfter,function(k,v){ 
  console.log(k);
  console.log(v);
  console.log("----");
});
/*
firstName 
Good 
----
lastName 
Man 
----
home 
1234567 
----
0 
7654321 
----
1 
999000 
----
work 
[]
----
phone 
Object 
----

Object 
----
*/

仔细看一下这些输出,可以发现这个遍历是由内而外的,可能由内而外这个词大家会误解,最里层是内部数组里的两个值啊,但是输出是从第一个属性开始的,怎么就是由内而外的呢?

这个由内而外指的是对于复合属性来说的,通俗地讲,遍历的时候,从头到尾进行遍历,如果是简单属性值(数值、字符串、布尔值和null),那么直接遍历完成,如果是遇到属性值是对象或者数组形式的,那么暂停,先遍历这个子JSON,而遍历的原则也是一样的,等这个复合属性遍历完成,那么再完成对这个属性的遍历返回。

本质上,这就是一个深度优先的遍历。

有两点需要注意:

  • 如果 reviver 返回 undefined,则当前属性会从所属对象中删除,如果返回了其他值,则返回的值会成为当前属性新的属性值。

  • 你可以注意到上面例子最后一组输出看上去没有key,其实这个key是一个空字符串,而最后的object是最后解析完成对象,因为到了最上层,已经没有真正的属性了。

3. 影响 JSON.stringify 的神奇函数——object.toJSON

如果你在一个JS对象上实现了toJSON方法,那么调用JSON.stringify去序列化这个JS对象时,JSON.stringify会把这个对象的toJSON方法返回的值作为参数去进行序列化。

var info={ 
  "msg":"I Love You",
  "toJSON":function(){
    var replaceMsg=new Object();
    replaceMsg["msg"]="Go Die";
    return replaceMsg;
  }
};

JSON.stringify(info); 
//出si了,返回的是:'"{"msg":"Go Die"}"',说好的忽略函数呢

这个函数就是这样子的。

其实Date类型可以直接传给JSON.stringify做参数,其中的道理就是,Date类型内置了toJSON方法。

四、小结以及关于兼容性的问题

到这里终于把,JSON和JS中的JSON,梳理了一遍,也对里面的细节和注意点进行了一次遍历,知道JSON是一种语法上衍生于JS语言的一种轻量级的数据交换格式,也明白了JSON相对于一般的JS数据结构(尤其是对象)的差别,更进一步,仔细地讨论了JS中关于JSON处理的3个函数和细节。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

jQuery操作json方法总结

.net实体类与json互相转换方法汇总

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn