(Це додано до моєї бібліотеки в GitHub )
Винахід колеса тут! Жодне з цих рішень не працювало для моєї ситуації. Отже, я швидко підкреслив відповідь Вільсона . Цей не призначений для друку на екран (за допомогою консолі, текстового поля чи іншого). Це добре працює в тих ситуаціях і працює добре, як цього вимагала ОП alert
. Багато відповідей тут не звертаються, використовуючи, alert
як вимагає ОП. Так чи інакше, він форматований для транспортування даних. Ця версія, здається, повертає дуже схожий результат toSource()
. Я не тестувався проти JSON.stringify
, але я припускаю, що це приблизно те саме. Ця версія більше схожа на поліфільм, так що ви можете використовувати його в будь-якому середовищі. Результатом цієї функції є дійсне оголошення об’єкта Javascript.
Я б не сумнівався, чи щось подібне вже було десь на SO, але це було просто коротше, ніж витратити час на пошук минулих відповідей. А оскільки це питання було моїм найкращим хітом у Google, коли я почав шукати про це; Я подумав, що його розміщення тут може допомогти іншим.
Так чи інакше, результатом цієї функції буде рядкове представлення вашого об'єкта, навіть якщо у ваш об’єкт вбудовані об'єкти та масиви, і навіть якщо ці об'єкти чи масиви ще більше вбудували об'єкти та масиви. (Я чув, що ти любиш пити? Отже, я переграв твою машину кулером. І тоді я переграв твій кулер кулером. Отже, ваш кулер може пити, поки ти крутий.)
Масиви зберігаються за допомогою, []
а {}
не мають пар ключів / значень, просто значень. Як і регулярні масиви. Тому вони створюються так, як це роблять масиви.
Крім того, всі рядки (включаючи імена ключів) цитуються, це не потрібно, якщо ці рядки не мають спеціальних символів (як пробіл чи коса риса). Але я не відчував, як виявити це лише для того, щоб видалити деякі цитати, які в іншому випадку все-таки добре працюватимуть.
Отриманий рядок потім може бути використаний з eval
або просто скиданням його в маніпуляцію вар-строком. Таким чином, знову створити об’єкт із тексту.
function ObjToSource(o){
if (!o) return 'null';
var k="",na=typeof(o.length)=="undefined"?1:0,str="";
for(var p in o){
if (na) k = "'"+p+ "':";
if (typeof o[p] == "string") str += k + "'" + o[p]+"',";
else if (typeof o[p] == "object") str += k + ObjToSource(o[p])+",";
else str += k + o[p] + ",";
}
if (na) return "{"+str.slice(0,-1)+"}";
else return "["+str.slice(0,-1)+"]";
}
Повідомте мене, якщо я все це зіпсував, добре справляється з моїм тестуванням. Крім того, єдиний спосіб я міг придумати для виявлення типу array
- це перевірити наявність length
. Оскільки Javascript дійсно зберігає масиви як об'єкти, я не можу насправді перевірити їх тип array
(такого типу немає!). Якщо хтось знає кращий спосіб, я б хотів це почути. Тому що, якщо у вашого об'єкта також є властивість з назвою, length
ця функція помилково трактує його як масив.
РЕДАКТУВАННЯ: Додано чек на об’єкти з нульовим значенням. Спасибі Брок Адамс
EDIT: Нижче наведена фіксована функція для друку нескінченно рекурсивних об'єктів. Це не друкується так само, як toSource
у FF, тому що toSource
буде надруковано нескінченну рекурсію один раз, де, як, ця функція негайно вб'є її. Ця функція працює повільніше, ніж описана вище, тому я додаю її сюди замість редагування вищевказаної функції, оскільки її потрібно лише в тому випадку, якщо ви плануєте десь передати об’єкти, які посилаються на себе.
const ObjToSource=(o)=> {
if (!o) return null;
let str="",na=0,k,p;
if (typeof(o) == "object") {
if (!ObjToSource.check) ObjToSource.check = new Array();
for (k=ObjToSource.check.length;na<k;na++) if (ObjToSource.check[na]==o) return '{}';
ObjToSource.check.push(o);
}
k="",na=typeof(o.length)=="undefined"?1:0;
for(p in o){
if (na) k = "'"+p+"':";
if (typeof o[p] == "string") str += k+"'"+o[p]+"',";
else if (typeof o[p] == "object") str += k+ObjToSource(o[p])+",";
else str += k+o[p]+",";
}
if (typeof(o) == "object") ObjToSource.check.pop();
if (na) return "{"+str.slice(0,-1)+"}";
else return "["+str.slice(0,-1)+"]";
}
Тест:
var test1 = new Object();
test1.foo = 1;
test1.bar = 2;
var testobject = new Object();
testobject.run = 1;
testobject.fast = null;
testobject.loop = testobject;
testobject.dup = test1;
console.log(ObjToSource(testobject));
console.log(testobject.toSource());
Результат:
{'run':1,'fast':null,'loop':{},'dup':{'foo':1,'bar':2}}
({run:1, fast:null, loop:{run:1, fast:null, loop:{}, dup:{foo:1, bar:2}}, dup:{foo:1, bar:2}})
ПРИМІТКА. Спроба друку document.body
- жахливий приклад. Для одного, FF просто виводить порожній рядок об'єкта при використанні toSource
. А при використанні функції вище, FF вимикається SecurityError: The operation is insecure.
. І Chrome вийде з ладу Uncaught RangeError: Maximum call stack size exceeded
. Зрозуміло, document.body
не передбачалося перетворення на рядок. Тому що або занадто великий, або проти політики безпеки для доступу до певних ресурсів. Якщо тільки я щось тут не зіпсував, скажіть!