anvoz
anvoz

Reputation: 722

Prevent function from looking for variables in outer scopes

I want to do this because my project usually uses shortcut variables like the below:

(function() {
    var world = new World(),
        Event = world.Event,
        Guide = world.Guide;

    Event.add('updateUI', function() {
        // 1st: Correct, the value of 'this' refers to a world
        this.Guide.show('UI updated');
        // 2nd: Ok because 'world' was defined in outer scope
        world.Guide.show('UI updated');
        // 3rd: Ok because 'Guide' was defined in outer scope
        Guide.show('UI updated');
    });
})();

If I move Event.add('updateUI', function() { ... }); to other file, only the first statement (this.Guide.show) works. How can I prevent this function from using the world or Guide variables of the outer scope so the second and third statements will throw errors from the beginning.

use strict is really close to this but it only prevent you from gaining access to the global object.

Updated to make this question clearer: The main question is: Are there any ways to prevent function from looking for variables in outer scopes? If there are no ways, please explain why because I think it's a reasonable need to do this.

Upvotes: 3

Views: 754

Answers (2)

Geekingfrog
Geekingfrog

Reputation: 191

You can use shadowing. If you explicitly declare the variable inside the function (and not initialize it), the function will use this variable instead of a variable of the same name from an outer scope.

Example:

var outer = 'foo';

function isolated () {
  var outer;
  console.log(outer);
};

isolated(); // output undefined

This should cover your needs.

There is another way, but it's an ugly hack and probably won't work on some browsers (IE ?).

Here is an example:

var outer = 'foo';

function isolated () {
  console.log(outer);
};

var e = eval;
// will throw exception: 'outer' is not defined
console.log(e('('+isolated.toString()+')()'));

eval and e are not exactly the same. The 'true' eval has access to the whole scope, but if you copy it, then the javascript engines can optimize it by not making the outer scope available to the evaled code.

However: Don't do that !

  • First: it relies on the fact that function.toString() will output the code of the function. This is not part of the specs and so is unreliable (works on v8 and spidermonkey though).
  • Second: eval should be avoided, it makes debugging a nightmare (you don't have access to a useful stack trace), there are performance and security issues, and you end up very quickly with an awful code to maintain.

Upvotes: 2

aaronps
aaronps

Reputation: 324

Don't know why would you like to do this, but using the short example:

(function(theFunk) {
    var world = new World(),
        Event = world.Event,
        Guide = world.Guide;

    Event.add('updateUI',theFunk);

})(function(){
        this.Guide.show('UI updated');  // 1st: depends on what you do with it
        world.Guide.show('UI updated'); // 2nd: will fail (depends on global)
        Guide.show('UI updated');       // 3rd: will fail (depends on global)
});

Upvotes: 0

Related Questions