如何在Javascript中创建静态变量?


当前回答

ES6类支持静态函数,其行为与其他面向对象语言中的静态函数非常相似:

class MyClass {
  static myFunction() {
    return 42;
  }
}

typeof MyClass.myFunction; // 'function'
MyClass.myFunction(); // 42

通用静态财产仍然是第三阶段的建议,这意味着您需要巴贝尔的第三阶段预设才能使用它们。但有了Babel,你可以做到这一点:

class MyClass {
  static answer = 42;
}

MyClass.answer; // 42

其他回答

您可以使用arguments.callee存储“静态”变量(这在匿名函数中也很有用):

function () {
  arguments.callee.myStaticVar = arguments.callee.myStaticVar || 1;
  arguments.callee.myStaticVar++;
  alert(arguments.callee.myStaticVar);
}

您可以利用JS函数也是对象这一事实,这意味着它们可以具有财产。

例如,引用Javascript中静态变量一文(现已消失)中给出的示例:

function countMyself() {
    // Check to see if the counter has been initialized
    if ( typeof countMyself.counter == 'undefined' ) {
        // It has not... perform the initialization
        countMyself.counter = 0;
    }

    // Do something stupid to indicate the value
    alert(++countMyself.counter);
}

如果多次调用该函数,您将看到计数器正在递增。

这可能是一个比用全局变量替换全局命名空间更好的解决方案。

下面是基于闭包的另一种可能的解决方案:在javascript中使用静态变量的技巧:

var uniqueID = (function() {
   var id = 0; // This is the private persistent value
   // The outer function returns a nested function that has access
   // to the persistent value.  It is this nested function we're storing
   // in the variable uniqueID above.
   return function() { return id++; };  // Return and increment
})(); // Invoke the outer function after defining it.

这会得到相同的结果——只是这次返回的是递增的值,而不是显示。

您可以使用static关键字在JavaScript中定义静态函数:

class MyClass {
  static myStaticFunction() {
    return 42;
  }
}

MyClass.myStaticFunction(); // 42

在撰写本文时,您仍然无法在类中定义静态财产(函数除外)。静态财产仍然是第三阶段的建议,这意味着它们还不是JavaScript的一部分。然而,没有什么可以阻止您像分配给任何其他对象一样简单地分配给类:

class MyClass {}

MyClass.myStaticProperty = 42;

MyClass.myStaticProperty; // 42

最后一点:小心使用带有继承的静态对象-所有继承的类共享对象的相同副本。

我经常使用静态函数变量,很遗憾JS没有内置的机制。我经常看到代码中的变量和函数是在外部范围内定义的,即使它们只是在一个函数内使用。这很难看,容易出错,而且只是自找麻烦。。。

我想出了以下方法:

if (typeof Function.prototype.statics === 'undefined') {
  Function.prototype.statics = function(init) {
    if (!this._statics) this._statics = init ? init() : {};
    return this._statics;
  }
}

这为所有函数添加了一个“statics”方法(是的,放松一下),当调用时,它将向函数对象添加一个空对象(_statics)并返回它。如果提供了init函数,_statics将设置为init()结果。

然后,您可以执行以下操作:

function f() {
  const _s = f.statics(() => ({ v1=3, v2=somefunc() });

  if (_s.v1==3) { ++_s.v1; _s.v2(_s.v1); }
} 

与另一个正确答案IIFE相比,这有一个缺点,即在每个函数调用中添加一个赋值和一个if,并向函数添加一个“_statics”成员,但也有一些优点:参数位于顶部而不是内部函数中,在内部函数代码中使用“static”是显式的,带有“_s”前缀,总体上看和理解起来更简单。

我通常使用这种方法有两个主要原因:

如果我想存储函数的本地值,我会使用“local.x”、“local.y”、“local.TempData”等。。。!

如果我想存储函数的静态值,我会使用“static.o”、“static.Info”、“static.count”等。。。!

[Update2]:方法相同,但使用IIFE方法!

[Update1]:通过预编辑脚本自动创建函数的“静态”和“本地”对象!