问题
Not sure I completely understand answers to similar questions that I found here, so trying to be absolutely sure:
I would like to have a local variable in a function, initialized only once (similar to static variables in strongly-typed languages such as C, C++, etc).
Of course, I could declare it globally, but it seems better practice to have it within the scope of that function, since it is not used anywhere else.
Now, here is what I do:
function func(data) {
func.PARAMS = [
{"name": "from", "size": 160, "indexed": true},
{"name": "input", "size": 256, "indexed": false},
{"name": "output", "size": 256, "indexed": false},
];
...
}
And my question is, will func.PARAMS
indeed be initialized only once, or will it be initialized every time the function is called?
According to some of the answers that I found (this one for example), I need to precede the initialization with something like:
if (typeof func.PARAMS == 'undefined')
This "supplemental" would be irrelevant in strongly-typed languages of course, so I just want to be sure that it is absolutely necessary in order to ensure "static behavior" (i.e., one-time initialization).
Thank you!!!
回答1:
In addition to using properties of the function object, as you do in your example, there are 3 other ways to emulate function-local static variables in Javascript.
All of them rely on a closure, but using different syntax.
Method 1 (supported in old browsers):
var someFunc1 = (function(){
var staticVar = 0 ;
return function(){
alert(++staticVar) ;
}
})() ;
someFunc1() ; //prints 1
someFunc1() ; //prints 2
someFunc1() ; //prints 3
Method 2 (also supported in old browsers):
var someFunc2 ;
with({staticVar:0})
var someFunc2 = function(){
alert(++staticVar) ;
} ;
someFunc2() ; //prints 1
someFunc2() ; //prints 2
someFunc2() ; //prints 3
Method 3 (requires support for EcmaScript 2015):
{
let staticVar = 0 ;
function someFunc3(){
alert(++staticVar) ;
}
}
someFunc3() ; //prints 1
someFunc3() ; //prints 2
someFunc3() ; //prints 3
回答2:
It would be assigned every time the function is called. There are no static
variables in JavaScript. You need to declare them outside of the function. You can do that in a local scope, though:
var func;
{
const PARAMS = [
{"name": "from", "size": 160, "indexed": true},
{"name": "input", "size": 256, "indexed": false},
{"name": "output", "size": 256, "indexed": false},
];
func = function(data) {
…
}
}
回答3:
While Javascript doesn't natively have the concept of static variables, it is easy to simulate them. One pattern with objects is to use a closure (via a self-invoking function).
const MyClass = ( function() {
// Static variables are in the scope of the self-invoking function
const _myStaticVariable = 'this is a static variable';
let _instances = 0; // this is also a class variable
// The constructor function is returned to MyClass, but still has the static variables in scope
return function() {
_instances++;
this.sayStaticVariable = function(){
console.log(_myStaticVariable);
}
this.howMany = function(){
console.log(_instances);
}
}
})();
myInstance = new MyClass();
myInstance.sayStaticVariable();
// this is a static variable
myInstance.howMany();
// 1
In this case, _myStaticVariable
and _instances
will only be initialised once, but will still be in scope of (and accessible to) the constructor function returned to MyClass.
As you seem to be asking about static variables in the context of functions rather than objects, you could probably adapt this pattern using functional composition
回答4:
JavaScript may look similar to C++ but in fact, it's very different. Initially, it's made for simple tasks in the browser. To mimic C++ like functionalities in JS programmers create complex structures. For example, in ES6 there are classes now but actually, they are just a syntactical sugar for constructor functions that rely on prototypal inheritance. In ES6 there now static methods you may want to check.
I guess in your case it will be better to use TypeScript that is more C# like and is a superset of JavaScript.
来源:https://stackoverflow.com/questions/48923021/javascript-local-static-variable