1

I am trying to have my application turn a json file into an object, which also has functions in it, but I don't know how to do this. This is my json file that won't work:

{
  "draw": function() {
    ctx.clearRect(0,0,960,720);
    ctx.fillStyle = "#000000";
  },
  "load": function() {
    if (beginning = 0) { erasePrev };
    loadHTML('button','level1Button',"position:absolute; top:100px; left:200px;",'LEVEL I','loadLevel(1)',false,false);
    loadHTML('a','howtoplayhref',"position:absolute; top:100px; left:100px;",'how to play',false,false,'howtoplay.html');
  },
  "clear": function() {
    removeHTML(level1Button);
    removeHTML(howtoplayhref);
  }
} 

I know how to load and parse the file, the problem is that it won't pass a json validator.

Mike Cluck
  • 31,869
  • 13
  • 80
  • 91

2 Answers2

1

JSON files are logic-less data representations. You can have objects with properties, arrays, integers, strings and booleans. You cannot have any logic stored in the file because a function represents a lot more than just the functionallity written in it (The scope for example). The whole idea of JSON files is to be easy to transport and easy to parse and use.

taxicala
  • 21,408
  • 7
  • 37
  • 66
1

You can't put a function in JSON. What you can do is put a string containing the function definition into the JSON, and then call eval() on this string to convert it into the corresponding function.

{
    draw: "(function() {
        ctx.clearRect(0,0,960,720);
        ctx.fillStyle = '#000000';
    })"
}

After loading the JSON, do:

var obj = JSON.parse(json_data);
obj.draw = eval(obj.draw);

Note that the parentheses around the function are important, otherwise eval doesn't parse it properly as a function expression.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thanks. I'll try using this. – user3581784 Sep 24 '15 at 17:09
  • bit late, but be aware of consequences of using `eval` – iLiA Jul 31 '20 at 20:48
  • @iLiA No worse than any other method of getting a function definition from an external site. – Barmar Jul 31 '20 at 20:50
  • Not sure what you are referring to – iLiA Jul 31 '20 at 20:56
  • @iLiA The whole point of this is to allow JSON data to contain a function definition. If you're executing a function that comes from JSON, it can do anything. So why is it any more dangerous to use `eval` to define the function in the first place? – Barmar Jul 31 '20 at 20:58
  • oh i did not mean it being dangerous, there are other cons of using eval – iLiA Jul 31 '20 at 20:59
  • Such as? You mean like the variable scope? – Barmar Jul 31 '20 at 20:59
  • eval() is also slower than the alternatives, since it has to invoke the JavaScript interpreter, while many other constructs are optimized by modern JS engines. Mozilla Developer – iLiA Jul 31 '20 at 21:00
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval – iLiA Jul 31 '20 at 21:00
  • i would prefer write that code into js file and export it as an object, if there was not any problem with that, it allows much more complex stuff to be written as values which JSON restricts – iLiA Jul 31 '20 at 21:01
  • if it is not node.js of course, there is alternative as mentioned in mozilla dev called `window.Function` – iLiA Jul 31 '20 at 21:04
  • @iLiA Most methods of defining functions dynamically from JSON data will suffer the same issues. The basic premise is what's problematic -- JSON is intended for language-independent data, and function definitions are inherently dependent on a specific language. – Barmar Jul 31 '20 at 21:29
  • I agree with that, although app is probably written in one language which uses that json and it is not probably shared between codebases, its still not recommended i suppose to use window.Function or eval. thats why native JS object seems to me as optimal solution for this – iLiA Jul 31 '20 at 21:42