0

I know the title sounds convoluted, but to keep things dynamic there is a purpose for this rest assured ;)

Examples (note that these example codes are assumed to be within an outer eval)

//Ex1 this works
eval('function test (){}');
test();

//Ex2 this doesn't work (myfunction definition is written below)
myfunction();
test(); //I get an error

If I defined myfunction globally (outside of the outer eval) I get this error: object is not a function

If I defined myfunction within the outer eval I get this error: object is not a function

//myfunction definition
function myfunction () {eval('function test (){}');}

Question is: how do I expand the scope of a function definition to just outside of the function it was defined within? I know about making an eval global (see alternate myfunction below), but that seems like overkill, I just want to increase the scope to the outer eval is all. Is this possible?

Update: The examples only define one function to keep is simple, but I wish expand it so that myfunction defines many functions, and what functions it defines is dynamic depending on other factors. Also I wish to retain the function names as well as the definitions. I may end up just putting the contents of myfunction into the outer eval if I can't find a solution other than making eval call globally, then I have to copy over the contents to everyplace that uses it.

//making eval global works, but I had hoped to just upscope to the calling eval
function myfunction(){var globaleval=eval;globaleval('function test(){}');}

Below has been edited since the initial question: Maybe you could make a var in outer eval, have myfunction return the address of the function definition to that var. However, I wish to retain the function names as well as the definitions.

user3015682
  • 1,215
  • 12
  • 13
  • You might want to read [Why is using the JavaScript eval function a bad idea?](http://stackoverflow.com/questions/86513/why-is-using-the-javascript-eval-function-a-bad-idea) – p.s.w.g Dec 06 '13 at 21:44
  • 6
    this...hurts... – Yuriy Galanter Dec 06 '13 at 21:45
  • 1
    Despite the obvious problem with `eval`, I wonder how you're surprised that `test()` doesn't work if you're defining a function named `bla`. All scoping issues aside. – Ingo Bürk Dec 06 '13 at 21:50
  • @IngoBürk Thanks for catching that, it was a typo, just corrected it – user3015682 Dec 06 '13 at 21:52
  • Why are you doing this? – epascarello Dec 06 '13 at 21:52
  • 3
    Am I the only one who did not understand what you are trying to achieve? – Givi Dec 06 '13 at 21:52
  • 1
    And what is this talk about a pointer to a function? Yes internally there are pointers, and sometimes when talking about certain aspects of Javascript using that word makes sense, but not how/where you used it. By the way, you are even wrong - if you used a variable to assign a function expression instead of using function declarations you could very well define the variable before assigning a function. Then you'd have your "pointer to function" (which will point to a function after an eventual assignment). – Mörre Dec 06 '13 at 21:53
  • @Mörre I think you may have answered the question in the form of a comment :) Based on what you've stated I'm going to attempt a solution to my problem! – user3015682 Dec 06 '13 at 22:01
  • Well, I won't write an "answer" because I don't want my name associated with the (or this) use of `eval()` :-) No really, I can't answer what I don't understand (your issues), but if no other answer comes close I suggest you write a good answer (to your own question!) and mark it as "answer", so that there's a good Q&A in the archive. – Mörre Dec 06 '13 at 22:04
  • So, what you're trying to do? declare functions as inner functions of myFunction and then made them global functions? and if so, why you using eval? you can achieve same result with global variables and function expressions. – Givi Dec 06 '13 at 22:28
  • If you add one more example of your code and expected result (may with pseudo code) it will help us to help you. – Givi Dec 06 '13 at 22:34

3 Answers3

2

OK, so I am assuming you actually mean you want to control the scope in which eval uses...

Why not

eval.call(context, 'function test(){}');

example

eval.call(window, 'function test(){}');
Ingo Bürk
  • 19,263
  • 6
  • 66
  • 100
iConnor
  • 19,997
  • 14
  • 62
  • 97
  • Thanks for the answer, is it possible to identify the context of the eval that called the function? – user3015682 Dec 06 '13 at 22:31
  • @user3015682 that makes no sense to me whatsoever, however you may be looking to use the `this` **keyword** as your context – iConnor Dec 07 '13 at 01:43
  • Thanks, passing the keyword this works: myfunction(this) then defining function myfunction(context) {eval.call(context,'function test(){}'); worked, and appears to do exactly like I wanted to do (I assume this refers to the outer eval context.) – user3015682 Dec 07 '13 at 05:18
  • Glad you've got it all sorted. Happy Coding! – iConnor Dec 07 '13 at 05:21
  • Oddly enough if I pass in a gibberish string in place of the keyword this it still works. Maybe eval.call simply makes it global for strings? The keyword this is an object not a string. – user3015682 Dec 07 '13 at 17:20
  • Heck, inside myfunction I could var a;context=a; and it will still work! It doesn't seem to care what context is as long as its defined! – user3015682 Dec 07 '13 at 20:32
1

eval() does execute within the local scope but that isn't your problem.

First, ditch eval()!

Second, think clearly on what you want without eval(). Even better please update the question when you have that.

Since I can't understand the actual question here are some guesses:

1. Reference to a particular object

If you want a reference to this of a particular object and the current context isn't sufficient Then use something like this question to "bind" (included in ecma 5) your new function to this.

You'll still have reference to the local closure of course.

2. Function that has a specific closure

If you want to call a function whose scope is "further out" or different than your "current scope" then define "that function" in the scope you want it to have (the closure) but then use a reference to "that function" that inner scope has

e.g.

var test='outer';
var outer = function (){   alert(test);}

(function(){
    var test='inner';
    var inner = function(){
        alert(outer());
    }
    inner();
})()

You'll note that inner() returns "outer" in this example

Community
  • 1
  • 1
gillyspy
  • 1,578
  • 8
  • 14
-1

in your second example function test() doesn't exists, because it's not defined yet )))

el Dude
  • 5,003
  • 5
  • 28
  • 40