0

If I were to make a new function using the Function constructor, how could I give it a non-temporary scope to access besides window (meaning the scope only has to be evaluated once, not every time the function is called)? The purpose is to construct multiple variables that require some pretty costly calculations, and I don't want to reconstruct them every time the function is called, but I also don't want to store them in window. Any ideas?

4 Answers 4

8

You could bind your function to the specific context using bind keyword:

var context = {};
var f = new Function("args", "return this").bind(context);
f(); // context

Since bind is defined in ECMA 5th, it may not be present in all browsers, here's a workaround

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

3 Comments

That's even better than Function.prototype.call! Thank you!
Thanks for that, but as it is, my program requires HTML5 to work, so the workaround would be pointless if the browser didn't support HTML5.
bind() sets this, not the global scope.
2

For the above described purpose, you use static functions. You cannot prevent scope from being evaluated at every call, because this is the way JavaScript works, but you can speed it up by not having window in the scoping chain.

var namespace = {};
namespace.someMethod = function() {
    // do something here.
};

Now anywhere in your code, you can call that method by using namespace.someMethod();. Just be careful. The above is a static method. You can call it without instantiating. But you MUST NOT use this.property inside a static function. It is a potentially very dangerous operation, as it may give an extension access to the global object and basically un-restricted permissions.

And the above is a static JavaScript method. It does not have window in the scoping chain.

Here's how to create a constructor using the same pattern. When you want to use a constructor, you always instantiate before using. For that you have the new keyword.

var namespace = {};
namespace.coordinate = function(x, y) {
    this.x = x;
    this.y = y;
};

namespace.coordinate.prototype.addCoordinates = function() {
    return this.x + this.y;


};

Now anywhere in your code you can do:

var coordinateObject = new namespace.coordinate(5,10);
// you have created a new instance.
alert(coordinateObject.addCoordinates());// will alert 15;
// now you can make as many as you want. They will behave as instances. 
// This means they do not interfere with each other in any way.
// They just have the same properties and methods, but the instance values
// Can be entirely different.

var secondCoordinateObject = new namespace.coordinate(10, 25);
alert(secondCoordinateObject.addCoordinates());// will output 35.

You have successufully created an instance of your namespace.coordinate class. Using the pattern I gave you, you can replicate almost the entire functionality of Java or C or any other Object Oriented language.

5 Comments

So I store the variables to namespace and refer to them through this[varName] within the function? I can't use static functions because I'm writing a JavaScript compiler for Complex math expressions.
Oh! I can do someMethod.call(namespace, arg0, arg1,... argN). I think that will work great!
The thing is, the function is for a specific purpose and will only be called for one reason, so the other answer works perfectly for what I'm doing.
Okay, I can see why this might work better... but my question is, is the namespace at all necessary to accomplish this? Or will coordinate and coordinate.prototype.addCoordinates work differently if coordinate is not attached to an Object?
The constructor will be inside an anonymous function, so my guess is, it will not interfere with anything else.
0
var yourNamespace = {

func1: function() {
},

func2: function() {
}
};

...

yourNamespace.func1();

you can call the function that you want by calling the function from name space like this yourNamespace.func1();

Comments

0

The ever-growing method of creating, storing, hiding, revealing, and grouping variables & functions is through the magic of "closures", Javascript's most powerful and yet unsung feature:

var groupObj = (function (setUp) {

    // maintained by reference, hidden
    var _priVar = setUp * 2; 

    // maintained by reference, revealed (through returned object)
    var _pubVar = 8;     
    var _pubFunc = function (x) {     
        _priVar += x;
        _pubVar += x;    
    }

    var lostVar = setUp * 99; // not referenced, hidden, so evaporates!

    return {    
        'pubVar' : _pubVar,
        'pubFunc' : _pubFunc    
    }

}(4)); // runs immediately with 4 as setUp, revealing pubVar & pubFunc

Then...

groupObj.pubFunc(7); // runs public function, adds 7 to both variables

alert('public variable: ' + groupObj.pubVar); // alerts public variable

A closure occurs whenever there is a function inside of another function. A variable inside of the outter function will be maintained so long as it is referenced by the inner function, kind of a "no-mans land" where a variable is forced to exist by a reference to it from a lower scope, but is hidden from the higher scope due to the innate principles of Javascript.

There are a few other ways to use closures, replacing the object constructor, one-off conflict-free private functions, and more. There are many posts here about them.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.