将对象转换为字符串


974

如何将JavaScript对象转换为字符串?

例:

var o = {a:1, b:2}
console.log(o)
console.log('Item: ' + o)

输出:

Object {a = 1,b = 2} //非常好的可读输出:)
项目:[object Object] //不知道里面有什么:(


7
转换为字符串有什么目的?您的意思是序列化,以便稍后可以从字符串构建对象?还是仅用于显示?
暗影巫师为您耳边

19
作者已经走了几年了,但请记住,几年后,我想这个问题的切入点是console.log(obj),它显示具有属性的对象,而console.log('obj:'+ obj )会使人迷失方向。
Danubian Sailor

2
根本不能应用添加两个对象,如果可以的话,值类型和引用类型将没有差异。
Nishant Kumar 2014年

12
var o = {a:1,b:2}; console.log('Item:'+ JSON.stringify(o))
Nishant Kumar

22
如果是用于控制台,我建议您这样做console.log("Item", obj);。不需要任何复杂的东西。
soktinpk

Answers:


1332

我建议使用JSON.stringify,它将对象中的变量集转换为JSON字符串。大多数现代浏览器都原生支持此方法,但对于不支持的浏览器,可以包含JS版本

var obj = {
  name: 'myObj'
};

JSON.stringify(obj);

7
作为参考,IE6和7不支持此功能。IE6没什么大不了的,因为用户很少,并且有积极的活动来杀死它……但是仍然有很多IE7用户(取决于您的用户群)。
MikeMurko

30
我收到“未捕获的TypeError:将圆形结构转换为JSON”。即使有循环引用,我仍然希望看到我的对象的字符串表示形式。我能做什么?
Pascal Klein

26
如果对象具有function属性,则此方法不起作用,例如:foo: function () {...}
布罗克·亚当斯

2
如果从StackOverflow中单击,则无法链接到JSON库。复制并将其粘贴到地址栏中。
f.ardelian

1
您可以使用JSON.stringify(obj, null, 2);更漂亮的输出。
l.poellabauer

126

使用javascript String()函数

 String(yourobject); //returns [object Object]

stringify()

JSON.stringify(yourobject)

28
var foo = {bar:1}; 字符串(foo); ->“ [object Object]”
Anti Veeranna

1
var foo = {bar:1}; 字符串(foo ['bar']); ->“ 1”
Vikram Pote

3
如果您希望将整个对象用作字符串,请使用JSON.stringify(foo)
Vikram Pote,

8
JSON.stringify(yourobject)女仆我的一天!
神经递质

1
@TranslucentCloud * made
Parampal Pooni

87

当然,要将对象转换为字符串,您必须使用自己的方法,例如:

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:578http://phpjs.org/functions/var_dump:604之类的东西

或者,如果您不使用方法(作为对象属性的函数),则可以使用新标准(但也可以在旧版浏览器中实现,尽管您也可以找到实用程序来帮助他们) .stringify()。但是同样,如果对象使用无法序列化为JSON的函数或其他属性,那将不起作用。


78

保持简单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


伟大的解决方案!但是当您简单地执行以下操作时,您能告诉我幕后发生了什么console.log(o)吗?由于如果您尝试记录添加到字符串中的对象,则实际上它会调用toString()该对象。
Gocy015 '16

1
console.log最终调用Printer了规范中注明的:“实现如何打印args取决于实现” –意味着每个浏览器都可以做到这一点(请参见console.spec.whatwg.org/#printer)。Firefox将对象显示为字符串,但是颜色很好。Chrome会将对象显示为交互式组,您可以展开该组以查看属性。试试看!
路加福音

2
非常好的技巧,对于现代的网络浏览器可能还不错,但是对于所有JS实现而言,它并不是100%可靠的。例如,在实现JS引擎的Qt QML中,for的输出console.log('Item: ', o);仍然是Item: [object Object]
Paul Masri-Stone

而不是console.log您可以使用console.dir(o)打印javascript对象,而是将其作为字符串打印。在开发人员工具中,这可以打开对象并检查所有属性,甚至包括数组。(请参阅:developer.mozilla.org/de/docs/Web/API/Console/dir
EagleT,

37

编辑 不要使用此答案,因为它在Internet Explorer中不起作用。使用Gary Chambers解决方案。

toSource()是您要查找的函数,它将以JSON形式写出。

var object = {};
object.first = "test";
object.second = "test2";
alert(object.toSource());

6
尽管在Firefox中调试很方便,toSource()但在IE中不起作用。
Brett Zamir

4
toSource()不是公认的标准,因此不能保证在所有浏览器中都受支持。
加里·钱伯斯

11
啊,谢谢你指出这一点。我将把答案留给不知道的人。
Gazler 2011年

我希望我能再投票给您,因为这对于具有javascript的环境来说是一个绝妙的解决方案(但是控制台日志不方便/无法访问)。
扎克·莫里斯

:你可以提供一个复方制剂,以toSource github.com/oliver-moran/toSource.js/blob/master/toSource.js
罗兰

32

一种选择

console.log('Item: ' + JSON.stringify(o));

o打印为字符串

另一个选项(如soktinpk在注释中指出的),对于控制台调试IMO更好:

console.log('Item: ', o);

o被打印为对象,如果您有更多字段,则可以向下钻取


22

这里没有任何解决方案对我有用。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)在此提出了一项改进意见:

这是一些经过更改的代码,可以处理“空”和“未定义”,并且也不会添加过多的逗号。

使用该工具需要您自担风险,因为我尚未对其进行验证。随意提出任何其他改进作为评论。


您缺少某些'}'s
dacopenhagen 2014年

2
非常好的代码,但是,每个对象/数组的末尾都有尾随。
NiCk Newman

这是最好的答案
Roman

20

如果您只是输出到控制台,则可以使用console.log('string:', obj)。注意逗号


在AJAX和deferred发挥作用的情况下,这会带来问题- AJAX完成向阵列并行提供数据后,console.log通常会显示来自的输出,这会导致产生误导的结果。在这种情况下,必须采用克隆或序列化对象的方法:由于我们记录了重复的对象,因此即使AJAX完成工作,它也会填充“旧”数据。
rr-

18

如果您知道对象只是布尔值,日期,字符串,数字等,则javascript String()函数可以正常工作。我最近发现这在处理来自jquery的$ .each函数的值时很有用。

例如,以下代码会将“值”中的所有项目转换为字符串:

$.each(this, function (name, value) {
  alert(String(value));
});

此处有更多详细信息:

http://www.w3schools.com/jsref/jsref_string.asp


var my_string = ''+value+'';
约翰·木兰

1
为我工作。我更喜欢这种解决方案,因为我不会将插件用于如此简单的任务。
Tillito

15
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);

12

我一直在寻找这个,并用缩进编写了一个很深的递归:

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" } })


注意,如果你要防止无限循环的循环引用的对象,您可以添加if(ndeep > MAX_DEPTH_LEVEL){ return '...'; }在功能,具有MAX_DEPTH_LEVEL为对象层您所选择的最大数量挖英寸
SylvainPV


9

1。

JSON.stringify(o);

项目:{“ 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}


1
如果您考虑添加有关答案的更多详细信息,将会更好。
Harun Diluka Heshan

8

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]

8

实际上,现有答案中缺少一个简单的选项(对于最新的浏览器和Node.js):

console.log('Item: %o', o);

我希望这样做JSON.stringify()有一定的局限性(例如,采用圆形结构)。


7

似乎JSON接受了第二个可能对函数有用的参数-replacer,这以最优雅的方式解决了转换问题:

JSON.stringify(object, (key, val) => {
    if (typeof val === 'function') {
      return String(val);
    }
    return val;
  });

5

如果只关心字符串,对象和数组:

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;
    }

5

stringify-object是yeoman团队制作的一个很好的npm库:https : //www.npmjs.com/package/stringify-object

npm install stringify-object

然后:

const stringifyObject = require('stringify-object');
stringifyObject(myCircularObject);

显然,只有当圆对象会因 JSON.stringify();


1
为什么有人会使用NPM模块来实现类似的功能,而这可以通过使用普通JS的单行代码实现呢?此答案需要有关为什么有人这样做的详细信息。
Zelphir Kaltstahl,

通常,lib将有助于解决极端情况。我用它来处理循环引用。
Nicolas Zozol '18

1
通过添加有关圆形对象的注释,这更有意义,从而消除了我的反对意见。
Zelphir Kaltstahl '18年


4

因为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(',')+'}';
}


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

2

如果可以使用lodash,则可以这样操作:

> var o = {a:1, b:2};
> '{' + _.map(o, (value, key) => key + ':' + value).join(', ') + '}'
'{a:1, b:2}'

使用lodash,map()您还可以遍历Objects。这会将每个键/值条目映射到其字符串表示形式:

> _.map(o, (value, key) => key + ':' + value)
[ 'a:1', 'b:2' ]

join()把数组项一起。

如果可以使用ES6模板字符串,那么它也可以:

> `{${_.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 } }'


1
/*
    This function is as JSON.Stringify (but if you has not in your js-engine you can use this)
    Params:
        obj - your object
        inc_ident - can be " " or "\t".
        show_types - show types of object or not
        ident - need for recoursion but you can not set this parameter.
*/
function getAsText(obj, inc_ident, show_types, ident) {
    var res = "";
    if (!ident)
        ident = "";
    if (typeof(obj) == "string") {
        res += "\"" + obj + "\" ";
        res += (show_types == true) ? "/* typeobj: " + typeof(obj) + "*/" : "";
    } else if (typeof(obj) == "number" || typeof(obj) == "boolean") {
        res += obj;
        res += (show_types == true) ? "/* typeobj: " + typeof(obj) + "*/" : "";
    } else if (obj instanceof Array) {
        res += "[ ";
        res += show_types ? "/* typeobj: " + typeof(obj) + "*/" : "";
        res += "\r\n";
        var new_ident = ident + inc_ident;
        var arr = [];
        for(var key in obj) {
            arr.push(new_ident + getAsText(obj[key], inc_ident, show_types, new_ident));
        } 
        res += arr.join(",\r\n") + "\r\n";
        res += ident + "]";
    } else {
        var new_ident = ident + inc_ident;      
        res += "{ ";
        res += (show_types == true) ? "/* typeobj: " + typeof(obj) + "*/" : "";
        res += "\r\n";
        var arr = [];
        for(var key in obj) {
            arr.push(new_ident + '"' + key + "\" : " + getAsText(obj[key], inc_ident, show_types, new_ident));
        }
        res += arr.join(",\r\n") + "\r\n";
        res += ident + "}\r\n";
    } 
    return res;
};

使用示例:

var obj = {
    str : "hello",
    arr : ["1", "2", "3", 4],
b : true,
    vobj : {
        str : "hello2"
    }
}

var ForReading = 1, ForWriting = 2;
var fso = new ActiveXObject("Scripting.FileSystemObject")
f1 = fso.OpenTextFile("your_object1.txt", ForWriting, true)
f1.Write(getAsText(obj, "\t"));
f1.Close();

f2 = fso.OpenTextFile("your_object2.txt", ForWriting, true)
f2.Write(getAsText(obj, "\t", true));
f2.Close();

your_object1.txt:

{ 
    "str" : "hello" ,
    "arr" : [ 
        "1" ,
        "2" ,
        "3" ,
        4
    ],
    "b" : true,
    "vobj" : { 
        "str" : "hello2" 
    }

}

your_object2.txt:

{ /* typeobj: object*/
    "str" : "hello" /* typeobj: string*/,
    "arr" : [ /* typeobj: object*/
        "1" /* typeobj: string*/,
        "2" /* typeobj: string*/,
        "3" /* typeobj: string*/,
        4/* typeobj: number*/
    ],
    "b" : true/* typeobj: boolean*/,
    "vobj" : { /* typeobj: object*/
        "str" : "hello2" /* typeobj: string*/
    }

}

1
最好能解释一下代码的作用以及如何使用它的示例。谢谢
estemendoza

1

例如,我认为 console.log("Item:",o) 这是最简单的。但是, console.log("Item:" + o.toString) 也可以。

使用方法一可以在控制台中使用一个不错的下拉菜单,因此长对象可以很好地工作。


1
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)+"}";
}

1

我希望这个例子对所有正在处理对象数组的人有所帮助

var data_array = [{
                    "id": "0",
                    "store": "ABC"
                },{
                    "id":"1",
                    "store":"XYZ"
                }];
console.log(String(data_array[1]["id"]+data_array[1]["store"]));

1

如果您不想玩join()到对象。

const obj = {one:1, two:2, three:3};
let arr = [];
for(let p in obj)
    arr.push(obj[p]);
const str = arr.join(',');

0

如果您想要一种针对内联表达式类型的情况将变量转换为字符串的极简方法,那''+variablename是我最好的选择。

如果'variablename'是一个对象并且您使用空字符串串联操作,它将给[object Object]您带来烦人的情况,在这种情况下,您可能希望Gary C. JSON.stringify对发布的问题大加赞赏的答案,您可以在Mozilla的开发人员网络上阅读该问题。在该答案顶部的链接中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.