(Это было добавлено в мою библиотеку на GitHub )
Изобретая колесо здесь! Ни одно из этих решений не помогло в моей ситуации. Итак, я быстро подправил ответ wilsonpage . Этот не для печати на экран (через консоль или текстовое поле или что-то еще). В этих ситуациях он отлично работает и работает так, как того требует OP alert
. Многие ответы здесь не относятся к использованию alert
в соответствии с запросом OP. Во всяком случае, однако, он отформатирован для передачи данных. Эта версия, кажется, возвращает очень похожий результат, как toSource()
. Я не проверял JSON.stringify
, но я предполагаю, что это примерно то же самое. Эта версия больше похожа на poly-fil, поэтому вы можете использовать ее в любой среде. Результатом этой функции является допустимое объявление объекта 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
эта функция будет ошибочно рассматривать его как массив.
РЕДАКТИРОВАТЬ: Добавлена проверка для объектов с нулевым значением. Спасибо Брок Адамс
РЕДАКТИРОВАТЬ: ниже фиксированная функция, чтобы иметь возможность печатать бесконечно рекурсивные объекты. Это не печатает так же, как 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
не предназначалось для преобразования в строку. Потому что либо слишком велик, либо против политики безопасности для доступа к определенным свойствам. Если я не испортил что-то здесь, скажи!