Интересный JSON.parse, JSON.stringify

регулярное выражение

предисловие

СейчасJSONФормат очень важен в веб-разработке, особенно в процессе использования ajax для разработки проектов часто бывает необходимоJSONОтформатированная строка возвращается во внешний интерфейс, и внешний интерфейс анализирует ее в значение объекта JS (JSONобъект), а затем визуализировать страницу. Во время передачи данныхJSONпередается в виде текста, то есть строки, а JS оперируетJSONобъект, значит,JSONобъект иJSONПреобразование между строками является ключевым.

1. Формат JSON

просто скажиJSONФормат,JSONФормат — это способ представления последовательности «значений», содержащихся в массивах или объектах, которые являются их членами.

Для этой серии «значений» указаны следующие форматы:

  • Значение каждого члена массива или объекта, которое может быть простым значением или составным значением.

  • Существует четыре типа простых значений: строки, числа (должны быть представлены в десятичном виде), логические значения иnull(NaN, Infinity, -Infinity和undefined都会被转为null).

  • Существует два типа составных значений:JSONФорматировать объекты и соответствоватьJSONМассив форматов.

  • Запятая не может быть добавлена ​​после последнего члена массива или объекта.

  • Строки в массивах или объектах должны заключаться в двойные, а не в одинарные кавычки.

  • Имена членов объекта должны заключаться в двойные кавычки.

Следующие имеют право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;
  }
} // 不能使用函数和日期对象

Уведомление⚠️:

И пустые массивы, и пустые объекты являются квалифицированными значениями JSON, и сам null также является квалифицированным значением JSON.

2. Разобрать JSON

Все современные браузеры поддерживаютJSON объект, есть два очень полезных метода для работы сJSONСодержимое формата:

JSON.parse(string): принимает строку JSON и преобразует ее вJavaScriptобъект.JSON.stringify(obj): принимает одинJavaScriptобъект и преобразовать его вJSONнить.

2.1 JSON.stringify()

пишуJavaScript, мы используемJSON.stringifyСериализирует значение в строковое значение для представления объекта.

Маленькие каштаны:

JSON.stringify({
    name: "Samara",
    country: "Jimbabwe"
});
// 输出结果:  "{"name":"Samara","country":"Jimbabwe"}"

JSON.stringify("Oh look, a string!");
// 输出结果: ""Oh look, a string!""

JSON.stringify([1,2,"open","the","door"]);
// 输出结果: "[1,2,"open","the","door"]"

Уведомление⚠️:

  1. неопределенные значения, функции или значения XML игнорируются
  2. Если ваш массив содержит неопределенные значения, функции или значения XML, эти значения в массиве будут рассматриваться как нулевые.

Возьмите другой каштан:

JSON.stringify({
    doStuff: function() { },
    doThings: [ function() {}, undefined ]
});
// 输出结果:  "{"doThings":[null,null]}"

анализировать:

В приведенном выше коде исходный объектdoStuffСвойство – это функция,JSON.stringifyСтрока, возвращаемая методом, не будет содержать этот атрибут. а такжеdoThingsСвойство представляет собой массив, членами которого являются функции иundefined, они превращаются вnull.

Обычные объекты преобразуются в пустые объекты.

JSON.stringify(/foo/) // "{}"

2.1.1 Метод JSON.stringify игнорирует непроходимые свойства объектов

var obj = {};
Object.defineProperties(obj, {
  'foo': {
    value: 1,
    enumerable: true
  },
  'bar': {
    value: 2,
    enumerable: false
  }
});

JSON.stringify(obj); // {"foo":1}

анализировать:Когда для свойства объекта установлено значение «непроходимый», используйтеJSON.stringifyЭта часть свойств игнорируется при обработке объекта. В приведенном выше кодеbarдаobjнепроходимые свойства объектов,JSON.stringifyметод игнорирует это свойство.

2.1.2 Второй параметр метода JSON.stringify

1. JSON.stringifyМетод также может принимать параметр массива, указывающий свойство, которое необходимо преобразовать в строку.
JSON.stringify({ a:1, b:2 }, ['a'])
// '{"a":1}'

анализировать:

В приведенном выше кодеJSON.stringifyВторой параметр метода указывает, что только поворотaАтрибуты.

2. Метод 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 o = {a: {b:1}};

function f(key, value) {
  console.log("["+ key +"]:" + value);
  return value;
}

JSON.stringify(o, f)
// []:[object Object] 
// [a]:[object Object]
// [b]:1
// '{"a":{"b":1}}'

анализировать:

В приведенном выше коде объектoвсего будетfФункция обрабатывается три раза. В первый раз, когда имя ключа пусто, значением ключа является весь объектo; имя второго ключаa, ключевое значение{b:1}; третий ключ называетсяb, ключевое значение1.

пункт два: при рекурсивной обработке объект, обрабатываемый каждый раз, является значением, возвращаемым предыдущим.

var o = {a: 1};

function f(key, value){
  if (typeof value === "object"){
    return {b: 2};
  }
  return value*2;
}

JSON.stringify(o,f)
// '{"b":4}'

В приведенном выше кодеfфункция изменяет объектo,тогдаJSON.stringifyметод для рекурсивной обработки измененного объектаo.

Пункт третий:Это свойство игнорируется, если обработчик возвращает значение undefined или не возвращает никакого значения.

function f(key, value) {
  if (typeof(value) == "string") {
    return undefined;
  }
  return value;
}

JSON.stringify({ a:"abc", b:123 }, f)
// '{"b":123}'

анализировать:

В приведенном выше коде после обработки свойства возвращается неопределенное значение, поэтому свойство игнорируется.

2.1.3 Третий параметр метода JSON.stringify

JSON.stringifyТакже может принимать третий параметр, используемый для увеличения возвращаемого значения.JSONЧитаемость строк.

Если это число, то это означает пробел, добавляемый перед каждым атрибутом (до 10); если это строка (до 10 символов), то строка будет добавляться перед каждой строкой.

(1) Когда третий параметр является числом

Следующий случай - когда третий параметр является числом:

// 这是一段应用程序中的调试标记日志
var person = {
    name: "Jim Cowart",
    location: {
        city: {
            name: "Chattanooga",
            population: 167674
        },
        state: {
            name: "Tennessee",
            abbreviation: "TN",
            population: 6403000
        }
    },
    company: "appendTo"
};

JSON.stringify(person)

// 我们得到的数据
'{"name":"Jim Cowart","location":{"city":{"name":"Chattanooga","population":167674},"state":{"name":"Tennessee","abbreviation":"TN","population":6403000}},"company":"appendTo"}'

// 我们期望的格式
"{
    "name": "Jim Cowart",
    "location": {
        "city": {
            "name": "Chattanooga",
            "population": 167674
        },
        "state": {
            "name": "Tennessee",
            "abbreviation": "TN",
            "population": 6403000
        }
    },
    "company": "appendTo"
}"

Если мы получаем фрагмент данных, но его читаемость не очень хорошая, и мы ожидаем, что он будет в нужном нам формате с лучшей читаемостью, самое время применитьJSON.stringifyтретий параметр.

var person = {
    name: "Jim Cowart",
    location: {
        city: {
            name: "Chattanooga",
            population: 167674
        },
        state: {
            name: "Tennessee",
            abbreviation: "TN",
            population: 6403000
        }
    },
    company: "appendTo"
};
//如果你希望缩进量为2 个空格,
// 你可以这么干:
JSON.stringify(person, null, 2);
/* produces:
"{
  "name": "Jim Cowart",
  "location": {
    "city": {
      "name": "Chattanooga",
      "population": 167674
    },
    "state": {
      "name": "Tennessee",
      "abbreviation": "TN",
      "population": 6403000
    }
  },
  "company": "appendTo"
}"
*/
// 如果你希望使用 tab 缩进,那么
// 你可以传入 \t 作为第三个参数
// 以此来告别空格缩进
JSON.stringify(person, null, "\t");
/*输出结果:
"{
    "name": "Jim Cowart",
    "location": {
        "city": {
            "name": "Chattanooga",
            "population": 167674
        },
        "state": {
            "name": "Tennessee",
            "abbreviation": "TN",
            "population": 6403000
        }
    },
    "company": "appendTo"
}"
*/

анализировать: Мы видим, что его второй параметр мы передаемnull, как было сказано выше, вторым параметром может быть массив или функция.

Если вторым аргументом является массив, будут выведены только те ключи, которые вы хотите включить в этот массив.

// 假定 person对象是上一例子中的那个,
JSON.stringify(person, ["name", "company"], 4);
/* 输出结果:
"{
    "name": "Jim Cowart",
    "company": "appendTo"
}"
*/

Если второй параметр является функцией, то функция должна иметь два параметра:keyа такжеvalue:

// a bit contrived, but it shows what's possible
// FYI - 被序列化的值是第一个传给replacerFn的东西, 也即是这个对象的每一个key,因此需要检查key的真假。
var replacerFn = function(key, value) {
    if(!key || key === 'name' || key === 'company') {
        return value;
    }
    return; //返回 undefined 并忽略 
}
JSON.stringify(person, replacerFn, 4);
/* produces:
"{
    "name": "Jim Cowart",
    "company": "appendTo"
}"
*/
(2) Когда третий параметр является строкой

Тогда есть еще один случай, когда третий параметр является строкой:

JSON.stringify({ p1:1, p2:2 }, null, "|-");
// "{
|-"p1": 1,
|-"p2": 2
}"

2.1.4 Объект, обрабатываемый методом JSON.stringify, включая метод toJSON

еслиJSON.stringifyОбъект, обрабатываемый методом, содержащийtoJSONметод, он будет использовать этот метод для получения значения, а затем преобразовать значение в строку, игнорируя другие элементы.

JSON.stringify({
  toJSON: function() {
    return "Cool"
  }
})
// "Cool""

var o = {
  foo: 'foo',
  toJSON: function() {
    return 'bar';
  }
};
var json = JSON.stringify({x: o}); 
// '{"x":"bar"}'

DateОбъект развертывает собственный метод toJSON.

JSON.stringify(new Date("2011-07-29"))
// "2011-07-29T00:00:00.000Z"

toJSONОдним из применений метода является автоматическое преобразование обычных объектов в строки.

RegExp.prototype.toJSON = RegExp.prototype.toString;

JSON.stringify(/foo/)
// "/foo/"

анализировать: Приведенный выше код развернут на прототипе обычного объекта.toJSONметод, укажите егоtoStringметод, поэтому встречи преобразуются вJSONКогда при первом вызове объект неtoJSONметод преобразуется в строку, которая затемJSON.stingifyобработка методом.

2.2 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') // null

var o = JSON.parse('{"name":"张三"}');
o.name // 张三

Если входящая строка имеет недопустимый формат JSON, метод JSON.parse сообщит об ошибке.

JSON.parse("'String'") // illegal single quotes
// SyntaxError: Unexpected token ILLEGAL

В приведенном выше коде строка в двойных кавычках является строкой в ​​одинарных кавычках, потому что строка в одинарных кавычках не соответствуетJSONформате, поэтому сообщается об ошибке.

Для обработки ошибок синтаксического анализа вы можете использоватьJSON.parseметод вtry...catchв кодовом блоке.

2.2.1 Второй параметр JSON.parse()

JSON.parseМетод может принимать функцию-обработчик, которая используется так же, какJSON.stringifyМетод похож.

function f(key, value) {
  if ( key === ""){
      return value;
  }
  if ( key === "a" ) {
    return value + 10;
  }
}

var o = JSON.parse('{"a":1,"b":2}', f);
o.a // 11
o.b // undefined

получать. . .

Как вы думаете, после прочтения мы можем сделать много вещей с помощью этих двух методов?