Is the usage of eval() justified here?
The JavaScript object data
has an attribute 'amplitudes' which is a string concatenated bunch of bitmask arrays coming from the server.
var data = {
"amplitudes":
"[1,1,1,4,1,1],[1,1,1,1,1,1],[1,1,4,1,9,1],[1,1,9,1,16,1],[1,32,1,1,1,9],[4,4,4,1,1,1]"
}
.
This needs be broken down into six independant arrays. I am using a combination of split()
and eval()
to accomplish it in the following way:
var amplitudes = [];
amplitudes = data.amplitudes.split("],[");
for(var i=0;i<amplitudes.length;i+=1){
(i+1)%2>0 ? amplitudes[i] = amplitudes[i] + "]" : amplitudes[i] = "[" + amplitudes[i];
amplitudes[i] = eval(amplitudes[i]);
}
Questions
1) Is there a more elegant and efficient way to do this?? I am not too happy with the usage of eval(), but had a feeling split is more efficient than a regex? I haven't run a benchmark yet.
2) I am also open to manipulating the format in which the field 'amplitudes' is stored in database so that my overall design gets simpler.
Suggestions welcome
As you probably process your data with a server-side language simply make it generate a JavaScript array. If you have an array in your server-side code, use a JSON encoder to build the JavaScript object/array.
var data = {
"amplitudes": [[1,1,1,4,1,1], [1,1,1,1,1,1], [1,1,4,1,9,1], [1,1,9,1,16,1], [1,32,1,1,1,9], [4,4,4,1,1,1]]
}
If you cannot change what you get from the server, you can do it using eval but in a much simpler way:
var str = "[1,1,1,4,1,1],[1,1,1,1,1,1],[1,1,4,1,9,1],[1,1,9,1,16,1],[1,32,1,1,1,9],[4,4,4,1,1,1]";
var arr = eval('[' + str + ']');
If you can change the server, just have the "amplitudes" property be an array of arrays, and don't write it out with quotes:
var data = {
amplitudes: [ [1, 1, 1, 4, 1, 1 ], [ 1, 1, 1, 1, 1, 1 ], ... ]
};
Now your client need do no decoding at all.
The eval() function is generally used to decode JSON data that is considered 'safe', as using eval on user-defined data can result in XSS attacks. Anyway, you can make your code more elegant by using regular expressions to match the arrays, then use eval to decode the array components:
var matches = data.amplitudes.match(/\[.*?\]/g);
var amplitudes = [];
if (matches != null && matches.length > 0) {
for (var i = 0; i < matches.length; i++) {
amplitudes[i] = eval(matches[i]);
}
}
Well you could try using JSON to pass a javascript object directly from the server, compared to just returning a string. Almost every server side language supports JSON encoding/decoding in some form.
http://www.json.org/
精彩评论