将一个对象转换为字符串

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个回答

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

我需要制作一个更加可配置的JSON.stringify版本,因为我需要添加注释并了解JSON路径:

const someObj = {
  a: {
    nested: {
      value: 'apple',
    },
    sibling: 'peanut'
  },
  b: {
    languages: ['en', 'de', 'fr'],
    c: {
      nice: 'heh'
    }
  },
  c: 'butter',
  d: function () {}
};

function* objIter(obj, indent = '  ', depth = 0, path = '') {
  const t = indent.repeat(depth);
  const t1 = indent.repeat(depth + 1);
  const v = v => JSON.stringify(v);
  yield { type: Array.isArray(obj) ? 'OPEN_ARR' : 'OPEN_OBJ', indent, depth };
  const keys = Object.keys(obj);
  
  for (let i = 0, l = keys.length; i < l; i++) {
    const key = keys[i];
    const prop = obj[key];
    const nextPath = !path && key || `${path}.${key}`;
 
    if (typeof prop !== 'object') {
      yield { type:  isNaN(key) ? 'VAL' : 'ARR_VAL', key, prop, indent, depth, path: nextPath };
    } else {
      yield { type: 'OBJ_KEY', key, indent, depth, path: nextPath };
      yield* objIter(prop, indent, depth + 1, nextPath);
    }
  }

  yield { type: Array.isArray(obj) ? 'CLOSE_ARR' : 'CLOSE_OBJ', indent, depth };
}

const iterMap = (it, mapFn) => {
  const arr = [];
  for (const x of it) { arr.push(mapFn(x)) }
  return arr;
}

const objToStr = obj => iterMap(objIter(obj), ({ type, key, prop, indent, depth, path }) => {
  const t = indent.repeat(depth);
  const t1 = indent.repeat(depth + 1);
  const v = v => JSON.stringify(v);

  switch (type) {
    case 'OPEN_ARR':
      return '[\n';
    case 'OPEN_OBJ':
      return '{\n';
    case 'VAL':
      return `${t1}// ${path}\n${t1}${v(key)}: ${v(prop)},\n`;
    case 'ARR_VAL':
      return `${t1}// ${path}\n${t1}${v(prop)},\n`;
    case 'OBJ_KEY':
      return `${t1}// ${path}\n${t1}${v(key)}: `;
    case 'CLOSE_ARR':
    case 'CLOSE_OBJ':
      return `${t}${type === 'CLOSE_ARR' ? ']' : '}'}${depth ? ',' : ';'}\n`;
    default:
      throw new Error('Unknown type:', type);
  }
}).join('');

const s = objToStr(someObj);
console.log(s);


这太棒了! - Brent Rittenhouse

1

添加附加项 ---

JSON.stringify(obj) 很好用, 但是它将转换为json字符串对象。 有时我们需要它的字符串形式,比如在WCF http post中以字符串形式发布它并接收。

为了达到这个目的,我们应该按以下方式重复使用 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

一个JSON字符串已经是一个字符串了。当进行POST请求时,您不应该需要对其进行双重编码。 - Phil

0
如果您正在使用Dojo JavaScript框架,则已经有一个内置函数可以实现此功能:dojo.toJson(),用法如下。
var obj = {
  name: 'myObj'
};
dojo.toJson(obj);

该函数将返回一个字符串。如果您想将对象转换为JSON数据,则需要添加第二个参数true。

dojo.toJson(obj, true);

http://dojotoolkit.org/reference-guide/dojo/toJson.html#dojo-tojson


0
如果您想要一种将变量转换为字符串的极简方法,以便在内联表达式类型的情况下使用,''+variablename 是我用过的最佳方法。
如果“variablename”是一个对象,并且您使用空字符串连接操作,则会得到令人烦恼的[object Object],这种情况下,您可能希望使用 Gary C. 极受欢迎的JSON.stringify答案回复发布的问题,在Mozilla的Developer Network上可以通过该答案顶部的链接阅读相关信息。

0
我使用了for in模板字面量,使得键值对都在字符串中,并且它对我起作用了。

let obj = {
  name: "John",
  age: 22,
  isDev: true,
};
let toStr = "";
for (let key in obj) {
  if (obj.hasOwnProperty(key)) {
    toStr += `${key} ${obj[key]}` + ", ";
  }
}
console.log(toStr);
console.log(typeof toStr);


0

这是在Angular 15中:

registerForm = new FormGroup({
  fname1: new FormControl(""),
  lname1: new FormControl(""),
  address1: new FormControl(""),
  address2: new FormControl(""),
  city1: new FormControl(""),
  state1: new FormControl(""),
  zip1: new FormControl("")

});

registerSubmited() {
alert(this.registerForm.value.fname1);
alert(this.registerForm.value.lname1);
alert(this.registerForm.value.address1);
alert(this.registerForm.value.address2);
alert(this.registerForm.value.city1);
alert(this.registerForm.value.state1);
alert(this.registerForm.value.zip1);
}

0
JavaScript异常"cyclic object value"在JSON中发现对象引用时发生。JSON.stringify()不会尝试解决这些问题,并相应地失败。
“JSON.stringify在某些情况下可能会失败”:出了什么问题?
JSON格式本身不支持对象引用(尽管有一个IETF草案存在),因此JSON.stringify()不会尝试解决它们,而是相应地失败。
TypeError: cyclic object value (Firefox) TypeError: Converting

circular structure to JSON (Chrome and Opera) TypeError: Circular

reference in value argument not supported (Edge)

JSON数据格式的规范作者提供的解决方案

/* JSON.decycle 
https://github.com/douglascrockford/JSON-js/blob/master/cycle.js
*/
if(typeof JSON.decycle!=="function"){JSON.decycle=function decycle(object,replacer){"use strict";var objects=new WeakMap();return(function derez(value,path){var old_path;var nu;if(replacer!==undefined){value=replacer(value)}
if(typeof value==="object"&&value!==null&&!(value instanceof Boolean)&&!(value instanceof Date)&&!(value instanceof Number)&&!(value instanceof RegExp)&&!(value instanceof String)){old_path=objects.get(value);if(old_path!==undefined){return{$ref:old_path}}
objects.set(value,path);if(Array.isArray(value)){nu=[];value.forEach(function(element,i){nu[i]=derez(element,path+"["+i+"]")})}else{nu={};Object.keys(value).forEach(function(name){nu[name]=derez(value[name],path+"["+JSON.stringify(name)+"]")})}
return nu}
return value}(object,"$"))}}


console.log(JSON.stringify(JSON.decycle(document))) 


-1
如果对象是 jQuery 对象,则应使用以下代码:
obj.html()

改为:

JSON.stringify(obj)

例子:

var tr = $('tr')

console.log('This does not work:')
console.log(JSON.stringify(tr))
console.log('But this does:')
console.log(tr.html())
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr><td>a</td><td>b</td>
</table>


OP询问的是“JavaScript对象”,而不是“jQuery” :) - Asfo

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