将Javascript对象(包括函数)转换为字符串

将Javascript对象(包括函数)转换为字符串,javascript,Javascript,嘿,我正在尝试将特定的javascript对象转换为字符串。到目前为止,我正在使用json2.js。只要我的对象包含函数,这些函数就会被剥离。我也需要一种转换函数的方法,有什么想法吗 firefox中的函数有一个toString()方法,但是如何使它与json2.js一起工作?简而言之,您不能将任意JavaScript函数转换为字符串。句号 有些运行时非常友好,可以为您定义的函数提供字符串序列化,但ECMAScript语言规范并不要求这样做。您提到的“toString()”示例是一个很好的例子,

嘿,我正在尝试将特定的javascript对象转换为字符串。到目前为止,我正在使用json2.js。只要我的对象包含函数,这些函数就会被剥离。我也需要一种转换函数的方法,有什么想法吗


firefox中的函数有一个toString()方法,但是如何使它与json2.js一起工作?

简而言之,您不能将任意JavaScript函数转换为字符串。句号


有些运行时非常友好,可以为您定义的函数提供字符串序列化,但ECMAScript语言规范并不要求这样做。您提到的“toString()”示例是一个很好的例子,说明了为什么不能这样做—该代码内置于解释器中,实际上可能不是用JavaScript实现的(而是实现运行时所用的语言)!还有许多其他函数可能具有相同的约束条件(例如构造函数、内置函数等)。

事实上,我认为这是可能的,也很简单。至少在使用nodeJS执行jsonP时,它对我来说很好,下面的例子可以说明这一点。 我只是简单地向函数添加字符串:

var anyString = '';
var aFunction = function() { return true; };
var functionToText = anyString + aFunction;
console.log(functionToText);
function convert(obj) {
  let ret = "{";

  for (let k in obj) {
    let v = obj[k];

    if (typeof v === "function") {
      v = v.toString();
    } else if (v instanceof Array) {
      v = JSON.stringify(v);
    } else if (typeof v === "object") {
      v = convert(v);
    } else {
      v = `"${v}"`;
    }

    ret += `\n  ${k}: ${v},`;
  }

  ret += "\n}";

  return ret;
}
这里是小提琴:

使用String()函数


结合几个选项

var aObj = { 
    v: 23,
    a: function() { 
        return true; 
    } 
};
var objStr = '';
for (var member in aObj) {
    objStr += (objStr ? ',\n': '')+
        member + ':' + aObj[member] + '';
}   

console.log('{\n'+
    objStr + '\n}');
functionName.toString()将返回包含所有函数代码的字符串。 我是在名字后面剪的

var funcString = CurrentButton.clickFunc.toString();
console.log("calling:" + funcString.substr(0, funcString.indexOf(")")-1));
//日志记录实用程序
变量日志=函数{
var d=document.getElementById('log');
var l=document.createElement('div');
l、 innerHTML=(typeof s=='object')?JSON.stringify(s):s;
d、 儿童(l);
}
//包装函数
var obj={
“x键”:{
“z”:函数(e){console.log(e);},
'a':[函数(e){console.log('array',e);},1,2]
},
‘s’:‘嘿,那里’,
n:100
};
日志(obj);
//将对象转换为字符串
功能otos(obj){
var-rs='';
var not_first=false;
用于(obj中的var k){
如果(不是_-first)rs+=',';
if(对象的类型[k]=“对象”){
rs+='“'+k+'”:{'+otos(obj[k])+'}';
}
else if(对象[k]的类型=='string'| |对象[k]的类型=='function'){
rs+='“'+k+'”:“+obj[k]+'”;
}
else if(对象类型[k]=“编号”){
rs+=“'+k+'”:“+obj[k]+”;
}
否则{
//如果它到了这里,那么我们需要添加另一个来处理它
控制台日志(obj[k]类型);
}
不首先=正确;
}
返回rs;
}
//将字符串转换为对象
功能图(str){
//我们递归地这样做,所以在第一个之后它将是一个对象
试一试{
var p_str=JSON.parse('{'+str+'}');
}捕获(e){var p_str=str;}
var obj={};
用于(p_str中的变量i){
如果(p_str[i]=='string'的类型){
if(p_str[i].子串(0,8)=‘函数’){
评估('obj[i]='+p_str[i]);
}
否则{
obj[i]=p_str[i];
}
}
else if(p_str[i]==='object'的类型){
obj[i]=stoo(p_str[i]);
}
}
返回obj;
}
//将对象转换为字符串
var s=otos(obj);
日志;
//将字符串转换为对象
var原始值=stoo(s);
日志(原件);
日志(原始_obj['x-keys'].z('hey');
日志(原始_obj['x-keys'].a[0]('hey'))

只需提供此函数的对象即可。(查找嵌套函数)此处:

功能恢复ejs(obj){
返回JSON.parse(JSON.stringify,obj,函数(k,v){
如果(v的类型==='函数'){
返回“\uuufn\uuuuuu”+v;
}
返回v;
}),函数(k,v){
if(typeof v=='string'&&v.indexOf('uuufn')!=-1){
返回v;
}
返回v;
});

}
使用以下功能将obj转换为str:

var anyString = '';
var aFunction = function() { return true; };
var functionToText = anyString + aFunction;
console.log(functionToText);
function convert(obj) {
  let ret = "{";

  for (let k in obj) {
    let v = obj[k];

    if (typeof v === "function") {
      v = v.toString();
    } else if (v instanceof Array) {
      v = JSON.stringify(v);
    } else if (typeof v === "object") {
      v = convert(v);
    } else {
      v = `"${v}"`;
    }

    ret += `\n  ${k}: ${v},`;
  }

  ret += "\n}";

  return ret;
}
输入 输出
我在@SIMDD函数的基础上做了一个改进版本,将所有类型的对象转换为字符串

打字脚本代码:

function anyToString(valueToConvert: unknown): string {
    if (valueToConvert === undefined || valueToConvert === null) {
        return valueToConvert === undefined ? "undefined" : "null";
    }
    if (typeof valueToConvert === "string") {
        return `'${valueToConvert}'`;
    }
    if (
        typeof valueToConvert === "number" ||
        typeof valueToConvert === "boolean" ||
        typeof valueToConvert === "function"
    ) {
        return valueToConvert.toString();
    }
    if (valueToConvert instanceof Array) {
        const stringfiedArray = valueToConvert
            .map(property => anyToString(property))
            .join(",");
        return `[${stringfiedArray}]`;
    }
    if (typeof valueToConvert === "object") {
        const stringfiedObject = Object.entries(valueToConvert)
            .map((entry: [string, unknown]) => {
                return `${entry[0]}: ${anyToString(entry[1])}`;
            })
            .join(",");
        return `{${stringfiedObject}}`;
    }
    return JSON.stringify(valueToConvert);
}
function anyToString(valueToConvert) {
    if (valueToConvert === undefined || valueToConvert === null) {
        return valueToConvert === undefined ? "undefined" : "null";
    }
    if (typeof valueToConvert === "string") {
        return `'${valueToConvert}'`;
    }
    if (typeof valueToConvert === "number" ||
        typeof valueToConvert === "boolean" ||
        typeof valueToConvert === "function") {
        return valueToConvert.toString();
    }
    if (valueToConvert instanceof Array) {
        const stringfiedArray = valueToConvert
            .map(property => anyToString(property))
            .join(",");
        return `[${stringfiedArray}]`;
    }
    if (typeof valueToConvert === "object") {
        const stringfiedObject = Object.entries(valueToConvert)
            .map((entry) => {
            return `${entry[0]}: ${anyToString(entry[1])}`;
        })
            .join(",");
        return `{${stringfiedObject}}`;
    }
    return JSON.stringify(valueToConvert);
}
香草Javascript代码:

function anyToString(valueToConvert: unknown): string {
    if (valueToConvert === undefined || valueToConvert === null) {
        return valueToConvert === undefined ? "undefined" : "null";
    }
    if (typeof valueToConvert === "string") {
        return `'${valueToConvert}'`;
    }
    if (
        typeof valueToConvert === "number" ||
        typeof valueToConvert === "boolean" ||
        typeof valueToConvert === "function"
    ) {
        return valueToConvert.toString();
    }
    if (valueToConvert instanceof Array) {
        const stringfiedArray = valueToConvert
            .map(property => anyToString(property))
            .join(",");
        return `[${stringfiedArray}]`;
    }
    if (typeof valueToConvert === "object") {
        const stringfiedObject = Object.entries(valueToConvert)
            .map((entry: [string, unknown]) => {
                return `${entry[0]}: ${anyToString(entry[1])}`;
            })
            .join(",");
        return `{${stringfiedObject}}`;
    }
    return JSON.stringify(valueToConvert);
}
function anyToString(valueToConvert) {
    if (valueToConvert === undefined || valueToConvert === null) {
        return valueToConvert === undefined ? "undefined" : "null";
    }
    if (typeof valueToConvert === "string") {
        return `'${valueToConvert}'`;
    }
    if (typeof valueToConvert === "number" ||
        typeof valueToConvert === "boolean" ||
        typeof valueToConvert === "function") {
        return valueToConvert.toString();
    }
    if (valueToConvert instanceof Array) {
        const stringfiedArray = valueToConvert
            .map(property => anyToString(property))
            .join(",");
        return `[${stringfiedArray}]`;
    }
    if (typeof valueToConvert === "object") {
        const stringfiedObject = Object.entries(valueToConvert)
            .map((entry) => {
            return `${entry[0]}: ${anyToString(entry[1])}`;
        })
            .join(",");
        return `{${stringfiedObject}}`;
    }
    return JSON.stringify(valueToConvert);
}
ATENTION


我正在使用函数Object.entries(),目前是草稿。因此,如果您没有使用Babel或typescript来传输代码,可以使用for循环或Object.keys()方法来替换它

所以我刚刚在我的一个项目上测试了您的脚本,但是包含特殊字符(如/或-)的对象键出现了问题

<>你应该考虑用引文包装这些键。

return `"${entry[0]}" : ${anyToString(entry[1])}`;

您可以事先将函数转换为字符串。但是为什么要这样做呢?事实上,
Function.prototype.toString()
是由规范定义的。@Pumbaa:当然,
toString()
方法是为每个对象定义的,但是不要求它序列化方法体或指令,我想OP指的是将函数作为JavaScript对象的属性。虽然您的解决方案确实适用于单个函数的简单情况,但对于OP的要求,它并不起作用(即使在迭代对象时)@RequiredCheese当在对象上迭代时,它确实起作用,您只是在迭代您定义的数组,而不是对象的成员。更新小提琴:正是我需要的。。。我在Firefox中使用了toSource(),但在Webkit/Blink中失败了。非常感谢。您好,请在回复中添加所有解决方案。请注意,如果您为对象提供循环引用,此函数将无休止地递归(堆栈溢出:),谢谢。这几乎是我需要的。我不得不添加另一个
if
语句:
elseif(typeof v=='boolean'){v=v;}
。太好了。好极了我会捐一百万给你!如何将其转换回?谢谢!这是我需要的无文档对象。如果您在某些项目中缺少文档,那么这将是非常好的选择。只需检查哪些函数集可用于替代引用列表。这是问题的答案吗?如果您试图更新其中一个答案,但您没有这样做的权限,只需将其放在该答案的评论部分。