How to use scope in JavaScript for Function constructor?

社会主义新天地 提交于 2019-12-12 04:58:55

问题


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?


回答1:


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.




回答2:


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




回答3:


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();




回答4:


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.



来源:https://stackoverflow.com/questions/13913401/how-to-use-scope-in-javascript-for-function-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!