Преобразование объекта в строку
Как я могу преобразовать объект JavaScript в строку?
Пример:
var o = {a:1, b:2}
console.log(o)
console.log('Item: ' + o)
Выход:
Object {a = 1, b = 2} // очень хороший читаемый вывод:)
Item: [object Object] // не знаю, что внутри:(
42 ответа
Я бы порекомендовал использовать JSON.stringify
, который преобразует набор переменных в объекте в строку JSON. Большинство современных браузеров изначально поддерживают этот метод, но для тех, которые этого не делают, вы можете включить версию JS:
var obj = {
name: 'myObj'
};
JSON.stringify(obj);
Используйте функцию String () javascript.
String(yourobject); //returns [object Object]
или же
JSON.stringify(yourobject)
,
Сохраняя это простым с console
, вы можете просто использовать запятую вместо +
, +
будет пытаться преобразовать объект в строку, тогда как запятая будет отображать его отдельно в консоли.
Пример:
var o = {a:1, b:2};
console.log(o);
console.log('Item: ' + o);
console.log('Item: ', o); // :)
Выход:
Object { a=1, b=2} // useful
Item: [object Object] // not useful
Item: Object {a: 1, b: 2} // Best of both worlds! :)
Ссылка: https://developer.mozilla.org/en-US/docs/Web/API/Console.log
Конечно, чтобы преобразовать объект в строку, вы должны либо использовать свой собственный метод, такой как:
function objToString (obj) {
var str = '';
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
str += p + '::' + obj[p] + '\n';
}
}
return str;
}
На самом деле, вышесказанное просто показывает общий подход; вы можете использовать что-то вроде http://phpjs.org/functions/var_export:578 или http://phpjs.org/functions/var_dump:604
или, если вы не используете методы (функции как свойства вашего объекта), вы можете использовать новый стандарт (но не реализованный в старых браузерах, хотя вы также можете найти для него утилиту), JSON.stringify(). Но опять же, это не сработает, если объект использует функции или другие свойства, которые нельзя сериализовать в JSON.
РЕДАКТИРОВАТЬ Не используйте этот ответ, так как он не работает в Internet Explorer. Используйте решение Гэри Чамберса.
toSource () - это функция, которую вы ищете, которая запишет ее как JSON.
var object = {};
object.first = "test";
object.second = "test2";
alert(object.toSource());
Один вариант:
console.log('Item: ' + JSON.stringify(o));
Другой вариант (как указано в комментариях к soktinpk) и лучше для отладки консоли IMO:
console.log('Item: ', o);
Ни одно из решений здесь не сработало для меня. Кажется, JSON.stringify - это то, что говорят многие люди, но он отключает функции и выглядит довольно неработоспособным для некоторых объектов и массивов, которые я пробовал при тестировании.
Я сделал свое собственное решение, которое работает как минимум в Chrome. Размещая его здесь, вы можете найти его в Google.
//Make an object a string that evaluates to an equivalent object
// Note that eval() seems tricky and sometimes you have to do
// something like eval("a = " + yourString), then use the value
// of a.
//
// Also this leaves extra commas after everything, but JavaScript
// ignores them.
function convertToText(obj) {
//create an array that will later be joined into a string.
var string = [];
//is object
// Both arrays and objects seem to return "object"
// when typeof(obj) is applied to them. So instead
// I am checking to see if they have the property
// join, which normal objects don't have but
// arrays do.
if (typeof(obj) == "object" && (obj.join == undefined)) {
string.push("{");
for (prop in obj) {
string.push(prop, ": ", convertToText(obj[prop]), ",");
};
string.push("}");
//is array
} else if (typeof(obj) == "object" && !(obj.join == undefined)) {
string.push("[")
for(prop in obj) {
string.push(convertToText(obj[prop]), ",");
}
string.push("]")
//is function
} else if (typeof(obj) == "function") {
string.push(obj.toString())
//all other values can be done with JSON.stringify
} else {
string.push(JSON.stringify(obj))
}
return string.join("")
}
РЕДАКТИРОВАТЬ: Я знаю, что этот код может быть улучшен, но просто не удосужился сделать это. Пользователь andrey предложил улучшение здесь с комментарием:
Вот немного измененный код, который может обрабатывать 'null' и 'undefined', а также не добавлять лишние запятые.
Используйте это на свой страх и риск, так как я не проверял это вообще. Не стесняйтесь предлагать любые дополнительные улучшения в качестве комментария.
Если вы просто выводите на консоль, вы можете использовать console.log('string:', obj)
, Обратите внимание на запятую.
В тех случаях, когда вы знаете, что объект представляет собой просто логическое значение, дату, строку, число и т. Д. Функция javascript String() работает просто отлично. Недавно я обнаружил, что это полезно при работе со значениями из функции $.each в jquery.
Например, следующий код преобразует все элементы в значении в строку:
$.each(this, function (name, value) {
alert(String(value));
});
Подробнее здесь:
var obj={
name:'xyz',
Address:'123, Somestreet'
}
var convertedString=JSON.stringify(obj)
console.log("literal object is",obj ,typeof obj);
console.log("converted string :",convertedString);
console.log(" convertedString type:",typeof convertedString);
Я искал это и написал глубоко рекурсивный с отступом:
function objToString(obj, ndeep) {
if(obj == null){ return String(obj); }
switch(typeof obj){
case "string": return '"'+obj+'"';
case "function": return obj.name || obj.toString();
case "object":
var indent = Array(ndeep||1).join('\t'), isArray = Array.isArray(obj);
return '{['[+isArray] + Object.keys(obj).map(function(key){
return '\n\t' + indent + key + ': ' + objToString(obj[key], (ndeep||1)+1);
}).join(',') + '\n' + indent + '}]'[+isArray];
default: return obj.toString();
}
}
Использование: objToString({ a: 1, b: { c: "test" } })
На самом деле в существующих ответах отсутствует одна простая опция (для последних браузеров и Node.js):
console.log('Item: %o', o);
Я бы предпочел это как JSON.stringify()
имеет определенные ограничения (например, с круговыми структурами).
Если вы просто хотите увидеть объект для отладки, вы можете использовать
var o = {a:1, b:2}
console.dir(o)
Похоже, JSON принимает второй параметр, который может помочь с функциями - replacer, это решает проблему преобразования самым элегантным способом:
JSON.stringify(object, (key, val) => {
if (typeof val === 'function') {
return String(val);
}
return val;
});
1.
JSON.stringify(o);
Item: {"a": "1", "b": "2"}
2.
var o = {a:1, b:2};
var b=[]; Object.keys(o).forEach(function(k){b.push(k+":"+o[k]);});
b="{"+b.join(', ')+"}";
console.log('Item: ' + b);
Предмет: {a:1, b:2}
Для не вложенных объектов:
Object.entries(o).map(x=>x.join(":")).join("\r\n")
Методы JSON значительно уступают примитиву движка Gecko.toSource().
См. Ответ на статью SO для сравнительных тестов.
Кроме того, ответ выше относится к http://forums.devshed.com/javascript-development-115/tosource-with-arrays-in-ie-386109.html/ который, как и JSON, (который другая статья http://www.davidpirek.com/blog/object-to-string-how-to-deserialize-json использует через "ExtJs JSON кодировать исходный код") не может обрабатывать циклические ссылки и является неполным. Приведенный ниже код показывает его (поддельные) ограничения (исправлено для обработки массивов и объектов без содержимого).
( прямая ссылка на код в //forums.devshed.com/... / tosource-with-arrays-in-ie-386109)
javascript:
Object.prototype.spoof=function(){
if (this instanceof String){
return '(new String("'+this.replace(/"/g, '\\"')+'"))';
}
var str=(this instanceof Array)
? '['
: (this instanceof Object)
? '{'
: '(';
for (var i in this){
if (this[i] != Object.prototype.spoof) {
if (this instanceof Array == false) {
str+=(i.match(/\W/))
? '"'+i.replace('"', '\\"')+'":'
: i+':';
}
if (typeof this[i] == 'string'){
str+='"'+this[i].replace('"', '\\"');
}
else if (this[i] instanceof Date){
str+='new Date("'+this[i].toGMTString()+'")';
}
else if (this[i] instanceof Array || this[i] instanceof Object){
str+=this[i].spoof();
}
else {
str+=this[i];
}
str+=', ';
}
};
str=/* fix */(str.length>2?str.substring(0, str.length-2):str)/* -ed */+(
(this instanceof Array)
? ']'
: (this instanceof Object)
? '}'
: ')'
);
return str;
};
for(i in objRA=[
[ 'Simple Raw Object source code:',
'[new Array, new Object, new Boolean, new Number, ' +
'new String, new RegExp, new Function, new Date]' ] ,
[ 'Literal Instances source code:',
'[ [], {}, true, 1, "", /./, function(){}, new Date() ]' ] ,
[ 'some predefined entities:',
'[JSON, Math, null, Infinity, NaN, ' +
'void(0), Function, Array, Object, undefined]' ]
])
alert([
'\n\n\ntesting:',objRA[i][0],objRA[i][1],
'\n.toSource()',(obj=eval(objRA[i][1])).toSource(),
'\ntoSource() spoof:',obj.spoof()
].join('\n'));
который отображает:
testing:
Simple Raw Object source code:
[new Array, new Object, new Boolean, new Number, new String,
new RegExp, new Function, new Date]
.toSource()
[[], {}, (new Boolean(false)), (new Number(0)), (new String("")),
/(?:)/, (function anonymous() {}), (new Date(1303248037722))]
toSource() spoof:
[[], {}, {}, {}, (new String("")),
{}, {}, new Date("Tue, 19 Apr 2011 21:20:37 GMT")]
а также
testing:
Literal Instances source code:
[ [], {}, true, 1, "", /./, function(){}, new Date() ]
.toSource()
[[], {}, true, 1, "", /./, (function () {}), (new Date(1303248055778))]
toSource() spoof:
[[], {}, true, 1, ", {}, {}, new Date("Tue, 19 Apr 2011 21:20:55 GMT")]
а также
testing:
some predefined entities:
[JSON, Math, null, Infinity, NaN, void(0), Function, Array, Object, undefined]
.toSource()
[JSON, Math, null, Infinity, NaN, (void 0),
function Function() {[native code]}, function Array() {[native code]},
function Object() {[native code]}, (void 0)]
toSource() spoof:
[{}, {}, null, Infinity, NaN, undefined, {}, {}, {}, undefined]
stringify-object
хорошая библиотека npm, созданная командой yeoman: https://www.npmjs.com/package/stringify-object
npm install stringify-object
затем:
const stringifyObject = require('stringify-object');
stringifyObject(myCircularObject);
Очевидно, это интересно, только если у вас есть круговой объект, который потерпит неудачу с JSON.stringify();
Поскольку Firefox не преобразует какой-либо объект в экранный объект; если вы хотите получить такой же результат, как: JSON.stringify(obj)
:
function objToString (obj) {
var tabjson=[];
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
tabjson.push('"'+p +'"'+ ':' + obj[p]);
}
} tabjson.push()
return '{'+tabjson.join(',')+'}';
}
может ты ищешь
JSON.stringify(JSON.stringify(obj))
"{\"id\":30}"
Если вы заботитесь только о строках, объектах и массивах:
function objectToString (obj) {
var str = '';
var i=0;
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if(typeof obj[key] == 'object')
{
if(obj[key] instanceof Array)
{
str+= key + ' : [ ';
for(var j=0;j<obj[key].length;j++)
{
if(typeof obj[key][j]=='object') {
str += '{' + objectToString(obj[key][j]) + (j > 0 ? ',' : '') + '}';
}
else
{
str += '\'' + obj[key][j] + '\'' + (j > 0 ? ',' : ''); //non objects would be represented as strings
}
}
str+= ']' + (i > 0 ? ',' : '')
}
else
{
str += key + ' : { ' + objectToString(obj[key]) + '} ' + (i > 0 ? ',' : '');
}
}
else {
str +=key + ':\'' + obj[key] + '\'' + (i > 0 ? ',' : '');
}
i++;
}
}
return str;
}
Взгляните на плагин jQuery-JSON
По своей сути он использует JSON.stringify, но возвращается к своему собственному парсеру, если браузер не реализует его.
Если вы можете использовать lodash, вы можете сделать это следующим образом:
> var o = {a:1, b:2};
> '{' + _.map(o, (value, key) => key + ':' + value).join(', ') + '}'
'{a:1, b:2}'
С Лодаш map()
Вы также можете перебирать объекты. Это сопоставляет каждую запись ключа / значения с ее строковым представлением:
> _.map(o, (value, key) => key + ':' + value)
[ 'a:1', 'b:2' ]
А также join()
положить записи массива вместе.
Если вы можете использовать ES6 Template String, это также работает:
> `{${_.map(o, (value, key) => `${key}:${value}`).join(', ')}}`
'{a:1, b:2}'
Обратите внимание, что это не идет рекурсивно через объект:
> var o = {a:1, b:{c:2}}
> _.map(o, (value, key) => `${key}:${value}`)
[ 'a:1', 'b:[object Object]' ]
Как узелutil.inspect()
Сделаю:
> util.inspect(o)
'{ a: 1, b: { c: 2 } }'
var o = {a:1, b:2};
o.toString=function(){
return 'a='+this.a+', b='+this.b;
};
console.log(o);
console.log('Item: ' + o);
Поскольку Javascript v1.0 работает везде (даже в IE), он является нативным подходом и позволяет очень экономно смотреть на ваш объект при отладке и в процессе производства https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
Полезный пример
var Ship=function(n,x,y){
this.name = n;
this.x = x;
this.y = y;
};
Ship.prototype.toString=function(){
return '"'+this.name+'" located at: x:'+this.x+' y:'+this.y;
};
alert([new Ship('Star Destroyer', 50.001, 53.201),
new Ship('Millennium Falcon', 123.987, 287.543),
new Ship('TIE fighter', 83.060, 102.523)].join('\n'));//now they can battle!
//"Star Destroyer" located at: x:50.001 y:53.201
//"Millennium Falcon" located at: x:123.987 y:287.543
//"TIE fighter" located at: x:83.06 y:102.523
Также в качестве бонуса
function ISO8601Date(){
return this.getFullYear()+'-'+(this.getMonth()+1)+'-'+this.getDate();
}
var d=new Date();
d.toString=ISO8601Date;//demonstrates altering native object behaviour
alert(d);
//IE6 Fri Jul 29 04:21:26 UTC+1200 2016
//FF&GC Fri Jul 29 2016 04:21:26 GMT+1200 (New Zealand Standard Time)
//d.toString=ISO8601Date; 2016-7-29
Циркулярные ссылки
Используя замену ниже, мы можем создать менее избыточный JSON - если исходный объект содержит множественные ссылки на какой-либо объект или содержит циклические ссылки - тогда мы ссылаемся на него специальной строкой пути (аналогично JSONPath) - мы используем ее следующим образом
let s = JSON.stringify(obj, refReplacer());
function refReplacer() {
let m = new Map(), v= new Map(), init = null;
return function(field, value) {
let p= m.get(this) + (Array.isArray(this) ? `[${field}]` : '.' + field);
let isComplex= value===Object(value)
if (isComplex) m.set(value, p);
let pp = v.get(value)||'';
let path = p.replace(/undefined\.\.?/,'');
let val = pp ? `#REF:${pp[0]=='[' ? '$':'$.'}${pp}` : value;
!init ? (init=value) : (val===init ? val="#REF:$" : 0);
if(!pp && isComplex) v.set(value, path);
return val;
}
}
// ---------------
// TEST
// ---------------
// gen obj with duplicate references
let a = { a1: 1, a2: 2 };
let b = { b1: 3, b2: "4" };
let obj = { o1: { o2: a }, b, a }; // duplicate reference
a.a3 = [1,2,b]; // circular reference
b.b3 = a; // circular reference
let s = JSON.stringify(obj, refReplacer(), 4);
console.log(s);
БОНУС: а вот обратная функция такой сериализации
function parseRefJSON(json) {
let objToPath = new Map();
let pathToObj = new Map();
let o = JSON.parse(json);
let traverse = (parent, field) => {
let obj = parent;
let path = '#REF:$';
if (field !== undefined) {
obj = parent[field];
path = objToPath.get(parent) + (Array.isArray(parent) ? `[${field}]` : `${field?'.'+field:''}`);
}
objToPath.set(obj, path);
pathToObj.set(path, obj);
let ref = pathToObj.get(obj);
if (ref) parent[field] = ref;
for (let f in obj) if (obj === Object(obj)) traverse(obj, f);
}
traverse(o);
return o;
}
// ------------
// TEST
// ------------
let s = `{
"o1": {
"o2": {
"a1": 1,
"a2": 2,
"a3": [
1,
2,
{
"b1": 3,
"b2": "4",
"b3": "#REF:$.o1.o2"
}
]
}
},
"b": "#REF:$.o1.o2.a3[2]",
"a": "#REF:$.o1.o2"
}`;
console.log('Open Chrome console to see nested fields:');
let obj = parseRefJSON(s);
console.log(obj);
function objToString (obj) {
var str = '{';
if(typeof obj=='object')
{
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
str += p + ':' + objToString (obj[p]) + ',';
}
}
}
else
{
if(typeof obj=='string')
{
return '"'+obj+'"';
}
else
{
return obj+'';
}
}
return str.substring(0,str.length-1)+"}";
}
Добавить ---
JSON.stringify(obj) хорош, но он преобразуется в строковый объект json. иногда нам понадобится его строка, например, при публикации в теле для публикации WCF http и получении в виде строки.
в порядке этого мы должны повторно использовать stringify() следующим образом:
let obj = {id:1, name:'cherry'};
let jsonObj = JSON.stringify(doc); //json object string
let strObj = JSON.stringify(jsonObj); //json object string wrapped with string
Для вашего примера я думаюconsole.log("Item:",o)
будет проще всего. Но,console.log("Item:" + o.toString)
также будет работать.
Использование метода номер один использует хороший выпадающий список в консоли, поэтому длинный объект будет работать хорошо.
Если все, что вам нужно, это просто получить строку вывода, то это должно работать: String(object)
Если вы используете JavaScript-каркас Dojo, то для этого уже есть встроенная функция: dojo.toJson(), которая будет использоваться следующим образом.
var obj = {
name: 'myObj'
};
dojo.toJson(obj);
который вернет строку. Если вы хотите преобразовать объект в данные json, добавьте второй параметр true.
dojo.toJson(obj, true);