49
function derp() { a(); b(); c(); } 

derp.toString() will return "function derp() { a(); b(); c(); }", but I only need the body of the function, so "a(); b(); c();", because I can then evaluate the expression. Is it possible to do this in a cross-browser way?

4
  • a(); b(); c(); is not a valid expression though... Commented Sep 1, 2012 at 12:35
  • @FelixKling: Why is it not valid? Commented Sep 1, 2012 at 12:41
  • 4
    @user1600680: ; separates statements and hence cannot be part of an expression. Everything that throws a syntax error when put into the grouping operator (...) is not a valid expressions. But maybe the OP did not refer to this technical meaning with the term expression. Commented Sep 1, 2012 at 12:42
  • Oh yeah, I guess to be correct there should be an "s" at the end of "expression" since it's 3 separate expression statements. Commented Sep 1, 2012 at 12:48

5 Answers 5

61
var entire = derp.toString(); var body = entire.slice(entire.indexOf("{") + 1, entire.lastIndexOf("}")); console.log(body); // "a(); b(); c();" 

Please use the search, this is duplicate of this question

Sign up to request clarification or add additional context in comments.

8 Comments

Use .slice. It's the same, but less confusing.
Do You mean var body = entire.slice(entire.indexOf("{") + 1, entire.lastIndexOf("}")); ?
Yes, I do. substring and substr generally confuse people. slice is a lot more memorable.
If you find a duplicate, then please flag the question as duplicate and if you reuse other answers then also cite them properly.
It won't work for functions that have parameters with default values. Example: function(myObj = {}) { console.log('Contents') }
|
11

Since you want the text between the first { and last }:

derp.toString().replace(/^[^{]*{\s*/,'').replace(/\s*}[^}]*$/,''); 

Note that I broke the replacement down into to regexes instead of one regex covering the whole thing (.replace(/^[^{]*{\s*([\d\D]*)\s*}[^}]*$/,'$1')) because it's much less memory-intensive.

1 Comment

toString() instead of toString but this is the cleanest answer I've found, thank you !
4

NOTE: The accepted answer depends on the interpreter not doing crazy things like throwing back comments between 'function' and '{'. IE8 will happily do this:

>>var x = function /* this is a counter-example { */ () {return "of the genre"}; >>x.toString(); "function /* this is a counter-example { */ () {return "of the genre"}" 

1 Comment

This is not an answer but a comment
3

A single-line, short regex example:

var body = f.toString().match(/^[^{]+\{(.*?)\}$/)[1]; 

If you want to, eventually, eval the script, and assuming the function takes no parameters, this should be a tiny bit faster:

var body = '(' + f.toString() + ')()'; 

1 Comment

Turning it into an IIFE statement for evaluation is the most robust solution if the function takes in no arguments. Works with ES6 arrow function syntax too.
2

You need something like this:

var content = derp.toString(); var body = content.match(/{[\w\W]*}/); body = body.slice(1, body.length - 1); console.log(body); // a(); b(); c(); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.