将一个对象转换为字符串

1202

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

示例:

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

输出:

对象 { a=1, b=2} // 非常良好易读 :)
条目: [object Object] // 不知道里面是什么 :(


7
将字符串转换为什么目的?你是指序列化,以便以后可以从字符串构建对象吗?还是只是为了显示? - Shadow The Spring Wizard
22
作者已经离开多年,但是在我脑海中阅读了多年后,我猜测问题的入口是console.log(obj),它会显示带有属性的对象,而console.log('obj: '+obj)则会产生迷惑。 - Danubian Sailor
2
无法简单地将两个对象相加,如果可以这样做,值类型和引用类型之间就没有区别了。 - Nishant Kumar
13
变量 o 等于 {a:1, b:2}; 打印出字符串 'Item: ' 和对象 o 的 JSON 字符串形式。 - Nishant Kumar
30
如果是针对控制台输出的话,我建议使用 console.log("Item", obj);。不需要过于复杂的代码。 - soktinpk
显示剩余7条评论
42个回答

5
也许你正在寻找的是:
JSON.stringify(JSON.stringify(obj))


"{\"id\":30}"

4
请看jQuery-JSON插件。
它的核心使用了JSON.stringify,但如果浏览器不支持,它会退而使用自己的解析器。

3
如果您能使用lodash,可以按照以下方式完成:
> var o = {a:1, b:2};
> '{' + _.map(o, (value, key) => key + ':' + value).join(', ') + '}'
'{a:1, b:2}'

使用Lodash的map()函数,您可以遍历对象。这将把每个键/值条目映射为其字符串表示:

> _.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]' ]

就像Node.js的util.inspect()一样:

> util.inspect(o)
'{ a: 1, b: { c: 2 } }'

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

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

循环引用

通过使用下面的替换器,我们可以生成更少冗余的 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);


1
我希望这个例子能够帮助所有正在处理对象数组的人。
var data_array = [{
                    "id": "0",
                    "store": "ABC"
                },{
                    "id":"1",
                    "store":"XYZ"
                }];
console.log(String(data_array[1]["id"]+data_array[1]["store"]));

1
使用修改后的 `reduce` 方法可以在检查最后一项时更改分隔符 `sep`,如下所示:
/**
     * Object to string
     * @param {*} obj 
     * @param {*} k_sep keys separator
     * @param {*} v_sep values separator
     * @returns 
     */
    var objectToString: function (obj, k_sep = '=', v_sep = ',') {
      const entries = Object.entries(obj);
      return entries.reduce((str, [p, val], counter) => {
        if (counter < entries.length - 1) {
          return `${str}${p}${k_sep}${val}${v_sep}`;
        } else {
          return `${str}${p}${k_sep}${val}`;
        }
      }, '');
    }

/**
 * Object to string
 * @param {*} obj 
 * @param {*} k_sep keys separator
 * @param {*} v_sep values separator
 * @returns 
 */
var objectToString = function(obj, k_sep = '=', v_sep = ',') {
  const entries = Object.entries(obj);
  return entries.reduce((str, [p, val], counter) => {
    if (counter < entries.length - 1) {
      return `${str}${p}${k_sep}${val}${v_sep}`;
    } else {
      return `${str}${p}${k_sep}${val}`;
    }
  }, '');
}

console.log(
  objectToString({
    status_code: 200,
    execute_time: 0.1,
    ip: '1270.0.0.1'
  }, ':', ","))
console.log(
  objectToString({
    status_code: 200,
    execute_time: 0.1,
    ip: '1270.0.0.1'
  }, '=', ","))


1

以下是一种简单的解决方案。

它仅显示字符串的 "",而不是数字和函数/方法(如果方法按此处所示编写):

  let obj = {
        name: "Philips TV",
        price: 2500,
        somemethod: function() {return "Hi there"}
  };
  
  let readableobj = '{ ';
  
  for(key in obj) {
    readableobj +=
    (typeof obj[key] === "string")? `${key}: "${obj[key]}", ` : `${key}: ${obj[key]}, `;
  }
 
  readableobj += '}';
  
  console.log('obj', readableobj); // obj { name: "Philips TV", price: 42, somemethod: function() {return "Hi there"}, }

这个解决方案使用尾随逗号(自ECMAScript 5起合法 - 参见MDN上的此处引用)。
代码基于最简单形式的“for in”循环:
let obj = {key: "value"};
for(key in obj) {
    return "The property " + key + " with value " + obj[key];
}

注意:它甚至适用于这种方法表示法:
  let obj = {
        name: "Philips TV",
        price: 2500,
        somemethod() {return "Hi there"}
  };

将结果显示为
    obj { name: "Philips TV", price: 42, somemethod: somemethod() {return "Hi there"}, } 

甚至对于箭头函数符号

  let obj = {
        name: "Philips TV",
        price: 2500,
        somemethod: () => {return "Hi there"}
  };

将结果显示为
    obj { name: "Philips TV", price: 42, somemethod: () => {return "Hi there"}, }

因此,即使一个对象内部包含所有三种方法符号(如下所示),您也可以以可接受的格式显示它。
  let obj = {
        name: "Philips TV",
        price: 2500,
        method1: function() {return "Hi there"},
        method2() {return "Hi there"},
        method3: () => {return "Hi there"}
  };

一个人可能会发现,即使第二种格式 method2() {return "Hi there"} 最终也被显示为一对 key: value ,通过复制它的标识符。
// method2: method2() {return "Hi there"}

最后,true / false, undefined, null 被视为数字和函数(最终格式中不显示""),因为它们也不是字符串。

重要提示

JSON.stringify() 会破坏原始对象,意味着其中的方法将丢失,并且在创建的最终字符串中不会显示。

因此,我们可能不应该接受涉及其使用的解决方案。

console.log('obj', JSON.stringify(obj)); // obj {"name":"Philips TV","price":2500} // which is NOT acceptable

1
如果你想将join()应用于Object。
const obj = {one:1, two:2, three:3};
let arr = [];
for(let p in obj)
    arr.push(obj[p]);
const str = arr.join(',');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接