admin管理员组

文章数量:1333736

Suppose that I have this code:

var cfg = {
  config: {
    fields: {
      name: {
        type: 'text'
      },
      age: {
        type: 'number'
      }
    },
    actions: [
      {
        label: 'Print',
        cb: (model) => {
          console.log(model);
        }
     }
   ]
  },
  data: {name: 'Jhon', age: 23}
}

And I want to convert it to a string (to let a user edit it) and then convert it back to executable code, any idea in how to achieve this?

I tried with JSON.stringify and JSON.parse but that will of course strip the functions. .toString returns "[object Object]", iterating on the object and call .toString when the values is a string, function or number is a possibility, any other idea?

Suppose that I have this code:

var cfg = {
  config: {
    fields: {
      name: {
        type: 'text'
      },
      age: {
        type: 'number'
      }
    },
    actions: [
      {
        label: 'Print',
        cb: (model) => {
          console.log(model);
        }
     }
   ]
  },
  data: {name: 'Jhon', age: 23}
}

And I want to convert it to a string (to let a user edit it) and then convert it back to executable code, any idea in how to achieve this?

I tried with JSON.stringify and JSON.parse but that will of course strip the functions. .toString returns "[object Object]", iterating on the object and call .toString when the values is a string, function or number is a possibility, any other idea?

Share Improve this question edited Aug 17, 2016 at 18:05 randominstanceOfLivingThing 18.8k13 gold badges52 silver badges73 bronze badges asked Aug 17, 2016 at 17:59 teoneteone 2,1833 gold badges27 silver badges49 bronze badges 3
  • 2 Do you really need your users to edit functions? – Bergi Commented Aug 17, 2016 at 18:11
  • Yes I need to, it is a tutorial on how to use and co figure UI ponenti, so I need the user to write some code and execute it – teone Commented Aug 17, 2016 at 18:58
  • Then you should start with a string, not with an object. Don't convert back and forth, only use eval on strings. For the initial code, put it in a string literal or load it from a file. – Bergi Commented Aug 17, 2016 at 19:13
Add a ment  | 

3 Answers 3

Reset to default 5

The Function constructor takes code as string, so does eval and a couple other. However, if in any way avoidable, do not convert code to string and backwards because of security concerns, ability to debug and a lot of other issues you can run into when doing so.

Converting code to a string is slightly annoying, because you need to make sure you don't redeclare variables and everything in the new context is syntactically correct, e.g. note that obj's f property is again named in the declaration, because it is later given to eval which places it in the global scope where it needs a name.

let obj = { f: function f() { let stuff = "hi"; console.log("hi"); } };
let code = obj.f.toString();
console.log(code);
eval(code);
f();

Note that JSON.stringify has an optional replacer parameter which can be used to customize the process.

I will again highly advise to avoid any code to/from string conversions when possible, in all normal cases this is not needed and should not be done.

You can iterate around that object and set it to inputs elements, like this

for (var key in cfg.config.fields) {
   console.log(key, cfg.config.fields[key].type);
   console.log(key, cfg.data[key],'data');
   console.log('<input type="'+cfg.config.fields[key].type+'" value="'+cfg.data[key]+'">')
}

This is the solution I came up with:

const toString = (code) => {
  if(Array.isArray(code)){
    return code.map(item => toString(item));
  }
  else if(typeof code == 'object'){
    let tmp = {};
    Object.keys(code).forEach(key => {
      tmp[key] = toString(code[key])
    });
    return tmp;
  }
  else{
    return code.toString().split('\n').join('').replace(/ +(?= )/gmi, '');
  }
};

This will iterate recursively across all the properties in a random JS structure (an object containing objects and arrays) an return the corresponding structure containing strings, you can then use JSON.stringify to get the actual string.

After the user edited it, it is executed with:

eval(`(${string})`);

As noted by other, be careful using eval, it can be dangerous (an interesting article is https://www.nczonline/blog/2013/06/25/eval-isnt-evil-just-misunderstood/)

本文标签: Javascript Convert code string and backStack Overflow