简体   繁体   English

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

[英]Convert Javascript Object (incl. functions) to String

Hey, Im trying to convert specific javascript objects to a String.嘿,我试图将特定的 javascript 对象转换为字符串。 So far I'm working with json2.js.到目前为止,我正在使用 json2.js。 As soon as my Object contain functions, those functions are stripped.一旦我的 Object 包含功能,这些功能就会被剥离。 I need a way to convert functions too, any ideas?我也需要一种转换函数的方法,有什么想法吗?

There is a toString() method for functions in firefox, but how to make that work with json2.js? firefox 中的函数有一个 toString() 方法,但是如何使它与 json2.js 一起工作?

Actually, I think it is possible and easy.实际上,我认为这是可能且容易的。 At least when doing jsonP with nodeJS it works for me just fine, and it's demonstratable by the following fiddle.至少在使用 nodeJS 执行 jsonP 时,它对我来说很好用,并且可以通过以下小提琴进行演示。 I did it by simply adding strings to a function:我通过简单地向函数添加字符串来做到这一点:

var anyString = '';
var aFunction = function() { return true; };
var functionToText = anyString + aFunction;
console.log(functionToText);

here's the fiddle: http://jsfiddle.net/itsatony/VUZck/这是小提琴: http : //jsfiddle.net/itsatony/VUZck/

Use String() function http://www.w3schools.com/jsref/jsref_string.asp使用 String() 函数http://www.w3schools.com/jsref/jsref_string.asp

var f = function(a, b){
    return a + b; 
}
var str = String(f);

The short answer is that you cannot convert arbitrary JavaScript functions to strings.简短的回答是您不能将任意 JavaScript 函数转换为字符串。 Period.时期。

Some runtimes are kind enough to give you the string serialization of functions you defined but this is not required by the ECMAScript language specification.一些运行时足以为您提供您定义的函数的字符串序列化,但这不是 ECMAScript 语言规范所要求的。 The "toString()" example you mentioned is a good example of why it cannot be done - that code is built in to the interpreter and in fact may not be implemented in JavaScript (but instead the language in which the runtime is implemented)!您提到的“toString()”示例是一个很好的例子,说明了为什么它不能完成 - 该代码内置于解释器中,实际上可能无法在 JavaScript 中实现(而是在实现运行时的语言中)! There are many other functions that may have the same constraints (eg constructors, built-ins, etc).还有许多其他函数可能具有相同的约束(例如构造函数、内置函数等)。

convert obj to str with below function:使用以下函数将 obj 转换为 str :

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

input输入

const input = {
  data: {
    a: "@a",
    b: ["a", 2]
  },

  rules: {
    fn1: function() {
      console.log(1);
    }
  }
}

const output = convert(input)

output输出

`{
  data: {
    a: "@a",
    b: ["a", 2]
  },
  rules: {
    fn1: function() {
      console.log(1);
    }
  }
}`

// typeof is String

Combining a few options结合几个选项

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

JSFiddle JSFiddle

functionName.toString() will return a string of all the function code. functionName.toString() 将返回所有函数代码的字符串。 I cut is after the name. I cut 是在名字之后。

var funcString = CurrentButton.clickFunc.toString();
console.log("calling:" + funcString.substr(0, funcString.indexOf(")")-1));

 // utility for logging var log = function(s){ var d = document.getElementById('log'); var l = document.createElement('div'); l.innerHTML = (typeof s === 'object')?JSON.stringify(s):s; d.appendChild(l); } // wrapper function var obj = { 'x-keys': { 'z': function(e){console.log(e);}, 'a': [function(e){console.log('array',e);},1,2] }, 's': 'hey there', 'n': 100 }; log(obj); // convert the object to a string function otos(obj){ var rs = ''; var not_first = false; for(var k in obj){ if(not_first) rs += ','; if(typeof obj[k] === 'object'){ rs += '"'+k+'": {'+otos(obj[k])+'}'; } else if(typeof obj[k] === 'string' || typeof obj[k] === 'function'){ rs += '"'+k+'":"'+obj[k]+'"'; } else if(typeof obj[k] === 'number'){ rs += '"'+k+'":'+obj[k]+''; } else { // if it gets here then we need to add another else if to handle it console.log(typeof obj[k]); } not_first = true; } return rs; } // convert a string to object function stoo(str){ // we doing this recursively so after the first one it will be an object try{ var p_str = JSON.parse('{'+str+'}'); }catch(e){ var p_str = str;} var obj = {}; for(var i in p_str){ if(typeof p_str[i] === 'string'){ if(p_str[i].substring(0,8) === 'function'){ eval('obj[i] = ' + p_str[i] ); } else { obj[i] = p_str[i]; } } else if(typeof p_str[i] === 'object'){ obj[i] = stoo(p_str[i]); } } return obj; } // convert object to string var s = otos(obj); log(s); // convert string to object var original_obj = stoo(s); log(original_obj); log( original_obj['x-keys'].z('hey') ); log( original_obj['x-keys'].a[0]('hey') );
 <div id='log'></div>

I realize this is very old but I have a solution here我意识到这已经很老了,但我在这里有一个解决方案

https://jsfiddle.net/stevenkaspar/qoghsxhd/2/ https://jsfiddle.net/stevenkaspar/qoghsxhd/2/

May not work for all cases but it is a good start可能不适用于所有情况,但这是一个好的开始

It will convert this into a string and then back into an object and you can run the functions它将把它转换成一个字符串,然后再转换回一个对象,你可以运行这些函数

var obj = {
  'x-keys': {
    'z': function(e){console.log(e);},
    'a': [function(e){console.log('array',e);},1,2]
  },
  's': 'hey there',
  'n': 100
};

Just provide the object to this function.只需向此函数提供对象即可。 (Look for nested function) Here: (寻找嵌套函数)这里:

 function reviveJS(obj) { return JSON.parse(JSON.stringify(obj, function (k, v) { if (typeof v === 'function') { return '__fn__' + v; } return v; }), function (k, v) { if (typeof v === 'string' && v.indexOf('__fn__') !== -1) { return v; } return v; }); }

UPDATE更新

A slightly decent code than above which I was able to solve is here http://jsfiddle.net/shobhit_sharma/edxwf0at/一个比上面我能够解决的稍微不错的代码在这里http://jsfiddle.net/shobhit_sharma/edxwf0at/

I made a improved version based on the @SIMDD function, to convert all types of objects to string.我基于@SIMDD 函数做了一个改进版本,将所有类型的对象转换为字符串。

Typescript code:打字稿代码:

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

Vanilla Javascript code:原生 Javascript 代码:

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!注意!

I am using the function Object.entries(), winch currently is a draft.我正在使用函数 Object.entries(),绞盘目前是一个草案。 So if you are not using Babel or typescript to transpile your code, you can replace it with a for loop or the Object.keys() method.因此,如果您不使用 Babel 或 typescript 来转译您的代码,则可以将其替换为 for 循环或 Object.keys() 方法。

I took one of answers above, it worked fine, but didn't inlcude case then array includes function.我接受了上面的一个答案,它工作正常,但不包括 case 然后数组包括 function。 So i modified it and it works fine for me.. Sharing the code.所以我修改了它,它对我来说很好。分享代码。

 function convert(obj,ret="{") { function check(v) { if(typeof v === "function") v = v.toString() else if (typeof v === "object") v = convert(v) else if (typeof v == "boolean" || Number.isInteger(v)) v=v else v = `"${v}"` return v } if(obj instanceof Array) { ret="[" obj.forEach(v => { ret += check(v)+',' }); ret += "\n]" } else { for (let k in obj) { let v = obj[k]; ret += `\n ${k}: ${check(v)},`; } ret += "\n}"; } return ret }

So I was just testing your script on one of my project, and there's a problem with Object keys that contain special characters (like / or -).所以我只是在我的一个项目上测试您的脚本,并且包含特殊字符(如 / 或 -)的对象键存在问题。

You should consider wrapping theses keys with quotes.您应该考虑用引号将这些键包装起来。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM