How to convert this string into a live function

I’ve this string:


function () { alert('Hello World!'); }

I want to convert it to a function that is ready to fire. Is it possible? How?

Thanks in advance,

Do you mean an IIFE – Immediately Invoked Function Expression (Pronounced: “Iffy”)

(function() { alert("Hello, World!"})();

Read more here: http://hughajwood.wordpress.com/2012/09/12/nothing-is-iffy-with-iife-in-javascript/

Or, upon reading your question again, maybe you mean to use eval(), which evaluates JavaScript code represented as a string.

If this is what you mean, please beware of the security implications, also mentioned in the above link.

Thanks for reply, but it’s not that.
It’s a string. Basically it is:


var a = "function () { alert('Hello World!'); }";

I want to make it a function when calls:


a();

I’ve tried that and it isn’t fired.

Ah ok, I understand now.

Some browsers can’t eval functions (presumably for security reasons).

One workaround is to put the function in an array, like this:

var funcStr = ["function() { alert('hello'); }"];
var func = eval('[' + funcStr + ']')[0];
func();

Reference: http://stackoverflow.com/questions/1271516/executing-anonymous-functions-created-using-javascript-eval

Might I ask why you are doing this?
What is it you are trying to achieve?
Maybe there is a better way to go about it.

Thanks, it works.

Is using eval() still dangerous in this case? It sounds scary.

Why I want to use this? My code is initially a (huge) function. For compression reason, I turn it to a base64 string and turn it back again for use. According to this post: http://labs.ft.com/2012/06/text-re-encoding-for-optimising-storage-capacity-in-the-browser/

It saves 63% space.

AFAIK, eval() only has security implications if you are parsing user input.
Somebody please correct me if I am wrong.

I think the whole eval() is evil issue is summarized quite well here.

Wow, that’s quite a saving. Nice one!

So, do I understand you correctly: you are compressing a large JS function using the compress function from point 3 of the article, you are then serving up the compressed function, decompressing it into a string (using the decompress function), then running the resultant string through eval, so as to execute the function?

 
<html>
<head>
<title></title>

<script type="text/javascript">

var str = "function a() { alert('hello'); }"; 
var el = document.createElement('script');
el.setAttribute('type','text/javascript');
el.text = str;
var h = document.getElementsByTagName('head')[0];
h.appendChild(el);
//alert( h.innerHTML );
</script>
</head>
<body>
<input type="button" value="click me" onclick="a()">
This code is working on 
&#304;nternet Explorer 8, 
Firefox 11.0, 
Firefox 4.0b9, 
Konqueror 4.5.5
</body>
</html>

@Pullo, exactly. This may help concealed my script which I don’t want to expose too, [as you can see on Apple Inc.'s website] => you know the secret now :slight_smile:

@muazzez, thank you. I’ll test it later on my home computer.

Is that how people say it? Man, I need to get with the times. :stuck_out_tongue: I think I would sound weird pronouncing it that way. “You need to write it as an iffy.”

I should point something out to you. Your script is being run in the user’s web browser, so at some stage your script must be turned in to executable scripting code, and the user will be able to eventually gain access to that code.

You are running scripting code in the users web browser, so your script is, by definition, made public when doing that.

Yeah, I think that’s how you pronounce it (at least that’s what i heard).
Someone please correct me if I am wrong.

@ketting00 ;
You could use muazzez’s suggestion and do the following, thus removing the need for eval()

function compress(s) {
  var i, l, out='';
  if (s.length % 2 !== 0) s += ' ';
  for (i = 0, l = s.length; i < l; i+=2) {
    out += String.fromCharCode((s.charCodeAt(i)*256) + s.charCodeAt(i+1));
  }
 
  // Add a snowman prefix to mark the resulting string as encoded (more on this later)
  return String.fromCharCode(9731)+out;
}

function decompress(s) {
  var i, l, n, m, out = '';
 
  // If not prefixed with a snowman, just return the (already uncompressed) string
  if (s.charCodeAt(0) !== 9731) return s;
 
  for (i = 1, l = s.length; i < l; i++) {
    n = s.charCodeAt(i);
    m = Math.floor(n/256);
    out += String.fromCharCode(m, n%256);
  }
  return out;
}

var funcString = "function(){ alert('Hello World!'); }",
    compressedFunc = compress("var func = " + funcString),
    decompressedFunc = decompress(compressedFunc),
    el = document.createElement('script'),
    h = document.getElementsByTagName('head')[0];
		
el.setAttribute('type','text/javascript');
el.text = decompressedFunc;
h.appendChild(el);
func();

@Pullo,

This is even exceeded my initial expectation.
You might wonder. I effectively reduce storage space from around 35kb+ to not over 20kb. More than 15kb space saved. I’m happier.
It is also handy to compress data client side before sending to a server.
As for loading speed, I don’t know how to measure.

Thank you,

One way of measuring performance would be using YSlow.
This is also an interesting read: http://www.html5rocks.com/en/tutorials/webperformance/basics/