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


当前回答

如果您想在应用程序中声明用于创建常量的静态变量,那么我发现以下是最简单的方法

ColorConstants = (function()
{
    var obj = {};
    obj.RED = 'red';
    obj.GREEN = 'green';
    obj.BLUE = 'blue';
    obj.ALL = [obj.RED, obj.GREEN, obj.BLUE];
    return obj;
})();

//Example usage.
var redColor = ColorConstants.RED;

其他回答

还有另一种方法,它解决了我浏览这个线程后的需求。这完全取决于您想要使用“静态变量”实现什么。

全局属性sessionStorage或localStorage允许在会话的生命周期内存储数据,或在明确清除之前存储不确定的更长时间。这允许在页面/应用程序的所有窗口、框架、选项卡面板、弹出窗口等之间共享数据,并且比一个代码段中的简单“静态/全局变量”功能强大得多。

它避免了顶级全局变量(如Window.myglobal)的范围、生存期、语义、动态等方面的所有麻烦。不知道它有多高效,但这对于以适度速度访问的少量数据来说并不重要。

轻松访问为“sessionStorage.mydata=anything”,并以类似方式检索。看见“JavaScript:最终指南,第六版”,David Flanagan,ISBN:978-0-596-80552-4,第20章,第20.1节。通过简单的搜索,或在O’Reilly Safaribooks订阅(价值黄金)中,可以轻松下载为PDF格式。

可以在声明静态变量后重新分配函数

function IHaveBeenCalled() {
  console.log("YOU SHOULD ONLY SEE THIS ONCE");
  return "Hello World: "
}
function testableFunction(...args) {
  testableFunction=inner //reassign the function
  const prepend=IHaveBeenCalled()
  return inner(...args) //pass all arguments the 1st time
  function inner(num) {
    console.log(prepend + num);
  }
}
testableFunction(2) // Hello World: 2
testableFunction(5) // Hello World: 5

这使用。。。args比较慢,有没有办法第一次使用父函数的作用域而不是传递所有参数?


我的用例:

function copyToClipboard(...args) {
  copyToClipboard = inner //reassign the function
  const child_process = require('child_process')
  return inner(...args) //pass all arguments the 1st time
  function inner(content_for_the_clipboard) {
    child_process.spawn('clip').stdin.end(content_for_the_clipboard)
  }
}

如果要在作用域之外使用child_process,可以将其分配给copyToCclipboard的属性

function copyToClipboard(...args) {
  copyToClipboard = inner //reassign the function
  copyToClipboard.child_process = require('child_process')
  return inner(...args) //pass all arguments the 1st time
  function inner(content_for_the_clipboard) {
    copyToClipboard.child_process.spawn('clip').stdin.end(content_for_the_clipboard)
  }
}

您可以通过IIFE(立即调用的函数表达式)执行此操作:

var incr = (function () {
    var i = 1;

    return function () {
        return i++;
    }
})();

incr(); // returns 1
incr(); // returns 2

2021更新

在2021,您可以简单地使用static关键字

截至2021 4月,TC39将STATIC关键字移至第4阶段语言功能。将静态JS特性变成一组正式的JS语言特性需要很长时间,然而,等待的原因是缺乏浏览器支持;现在,主流浏览器支持static关键字,并支持公共静态字段和私有静态字段的开放季节。



下面是实现静态JavaScript类成员的新方法的一般示例

class ColorFinder {
  static #red = "#ff0000";
  static #green = "#00ff00";
  static #blue = "#0000ff";
  
  static colorName(name) {
    switch (name) {
      case "red": return ColorFinder.#red;
      case "blue": return ColorFinder.#blue;
      case "green": return ColorFinder.#green;
      default: throw new RangeError("unknown color");
    }
  }
  
  // Somehow use colorName
}

以上示例取自TC39存储库,静态字段



要了解更多关于这个新的JS语言特性的实现(单击此处)。

阅读更多关于该特性本身的信息,以及演示静态字段语法的示例(单击此处)。

我没有在任何答案中看到这个想法,所以只是将其添加到列表中。如果是重复的,请告诉我,我会删除它并对另一个进行投票。

我在我的网站上创建了一种超级全球化。由于每次页面加载时都会加载几个js文件,而其他几十个js文件只加载在一些页面上,所以我将所有“全局”函数都放在一个全局变量中。

在我第一个包含的“全局”文件的顶部是声明

var cgf = {}; // Custom global functions.

然后我删除了几个全局助手函数

cgf.formBehaviors = function()
{
    // My form behaviors that get attached in every page load.
}

然后,如果我需要一个静态变量,我只需将其存储在范围之外,例如文档就绪或行为附件之外。(我使用jquery,但它应该在javascript中工作)

cgf.first = true;
$.on('click', '.my-button', function()
{
    // Don't allow the user to press the submit twice.
    if (cgf.first)
    {
        // first time behavior. such as submit
    }
    cgf.first = false;
}

这当然是一个全局的,而不是静态的,但由于它在每次加载页面时都会重新初始化,所以它可以达到相同的目的。