JSON.stringify игнорирует некоторые члены объекта

Вот простой пример.

function Person() {
  this.name = "Ted";
  this.age = 5;
}

persons[0] = new Person();
persons[1] = new Person();
JSON.stringify(persons);

Если у меня есть массив объектов Person, и я хочу преобразовать их в строки. Как я могу вернуть JSON только с переменной имени.

Причина этого в том, что у меня есть большие объекты с рекурсивными ссылками, которые вызывают проблемы. И я хочу удалить рекурсивные переменные и другие из процесса stringify.

Спасибо за любую помощь!


person Moz    schedule 15.09.2011    source источник


Ответы (4)


Я бы создал новый массив:

var personNames = $.map(persons,function(person){
  return person.name;
});
var jsonStr = JSON.stringify(personNames);
person Kevin B    schedule 15.09.2011
comment
как бы это было, если бы я хотел вернуть несколько значений, мог бы я поместить их в массив? У меня сейчас нет доступа к моему коду, чтобы попробовать самому, извините. - person Moz; 16.09.2011
comment
вы бы вернули карту свойств, например return { name: person.name, id: person.id }; - person Kevin B; 16.09.2011
comment
Я не могу заставить это работать, используя ваш код, я просто возвращаю весь объект человека. Вы уверены, что это правильно? Примеры для .grep в jQuery API используют функцию для возврата логического значения, которое определяет, включен ли весь объект в массив. Не определять, какие переменные включены. - person Moz; 16.09.2011
comment
Извините, я использую неправильный метод. это должно быть $.map, я обновлю ответ. - person Kevin B; 16.09.2011
comment
еще одна вещь, в настоящее время возвращается объект. Мне действительно нужны массивы данных, массивы внутри одного массива. Есть простой способ сделать это? - person Moz; 16.09.2011
comment
в точку, большое спасибо. Я уже пробовал что-то подобное, но у меня не было второго набора квадратных скобок, поэтому все были в одном гигантском массиве, теперь это 2D, спасибо. - person Moz; 17.09.2011

самым простым ответом было бы указать свойства для строки

JSON.stringify( persons, ["name"] )

другим вариантом было бы добавить метод toJSON к вашим объектам

function Person(){
  this.name = "Ted";
  this.age = 5;      
}
Person.prototype.toJSON = function(){ return this.name };

подробнее: http://www.json.org/js.html

person lordvlad    schedule 30.12.2012
comment
Это кажется лучшим ответом, чем принятый ответ. Вы можете использовать аргумент replacer для написания функции, которая будет исключать w/e свойства, которые вы не хотите сериализовать в объекте. - person Josh M.; 27.03.2013

Если вы поддерживаете только среды, совместимые с ECMAScript 5, вы можете сделать свойства, которые должны быть исключены, неперечислимыми, установив их с помощью Object.defineProperty()[docs] или Object.defineProperties()[docs].

function Person() {
    this.name = "Ted";
    Object.defineProperty( this, 'age', {
        value:5,
        writable:true,
        configurable:true,
        enumerable:false // this is the default value, so it could be excluded
    });
}

var persons = [];

persons[0] = new Person();
persons[1] = new Person();

console.log(JSON.stringify(persons));  // [{"name":"Ted"},{"name":"Ted"}]
person user113716    schedule 15.09.2011
comment
Просто общий вопрос из-за моего невежества ... Какой разработчик поддерживает только ECMAScript 5 и над чем он работает? На чем работает ECMAScript 5 и т. д.? - person Allen Rice; 16.09.2011
comment
@Allen: внутренние приложения для закрытых сред, в которых гарантирован тип/версия браузера. Или код на стороне сервера, хотя это менее вероятно из-за включения OP тега jQuery. На чем работает ECMAScript 5 и т. п.? Если вы имеете в виду, какие среды поддерживают ES 5, ознакомьтесь с таблица совместимости ES 5 от Kangax. - person user113716; 16.09.2011
comment
Спасибо! Я увидел эту таблицу после некоторых исследований, после публикации комментария выше :) Похоже, что уже существует множество браузеров, реализующих эти функции, очень интересно! - person Allen Rice; 16.09.2011
comment
Спасибо, ребята, могу ли я использовать что-то похожее на методы игнорирования? У меня есть вызов функции локального метода во время создания моего объекта, например. this.method(), и это приводит к тому, что stringify все еще путается (циклическое значение объекта) - person Moz; 16.09.2011
comment
@Moz: этот метод используется только во время построения или он должен быть членом объекта .prototype конструктора. - person user113716; 16.09.2011
comment
@Moz: Тогда не делайте это собственностью this. Если он используется только в строительстве, то просто сделайте его обычной функцией в конструкторе: function my_method() {...}. Если вы хотите, чтобы this внутри функции ссылалась на тот же объект, на который ссылается this, вызовите его как my_method.call( this ). Это установит значение this внутри функции на такое же значение this снаружи. - person user113716; 16.09.2011
comment
Интересный подход, почему stringify работает только с перечислимыми свойствами? Это где-то указано? - person Benjamin Gruenbaum; 31.03.2013

см. этот пост указать поле, которое вы хотите включить. JSON.stringify(person,["name","Address", "Line1", "City"]) соответствует лучше, чем то, что было предложено выше!

person moshe beeri    schedule 23.08.2015