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


当前回答

我经常使用静态函数变量,很遗憾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”前缀,总体上看和理解起来更简单。

其他回答

如果您来自基于类的静态类型的面向对象语言(如Java、C++或C#),我假设您试图创建与“类型”相关联的变量或方法,而不是与实例相关联的。

使用带有构造函数的“经典”方法的示例可能会帮助您了解基本OO JavaScript的概念:

function MyClass () { // constructor function
  var privateVariable = "foo";  // Private variable 

  this.publicVariable = "bar";  // Public variable 

  this.privilegedMethod = function () {  // Public Method
    alert(privateVariable);
  };
}

// Instance method will be available to all instances but only load once in memory 
MyClass.prototype.publicMethod = function () {    
  alert(this.publicVariable);
};

// Static variable shared by all instances
MyClass.staticProperty = "baz";

var myInstance = new MyClass();

staticProperty在MyClass对象(这是一个函数)中定义,与它创建的实例无关,JavaScript将函数视为一级对象,因此作为一个对象,可以将财产分配给函数。

UPDATE:ES6引入了通过class关键字声明类的能力。它是现有的基于原型的继承的语法糖。

static关键字允许您轻松定义类中的静态财产或方法。

让我们看看上面用ES6类实现的示例:

类MyClass{//类构造函数,等效于//构造函数的函数体构造器(){const privateVariable=“private value”;//构造函数范围内的私有变量this.publicVariable='公共值';//公共财产this.privilegedMethod=函数(){//具有构造函数范围变量访问权限的公共方法console.log(privateVariable);};}//原型方法:publicMethod(){console.log(this.publicVariable);}//所有实例共享的静态财产static staticProperty='静态值';静态静态方法(){console.log(this.staticProperty);}}//我们可以将财产添加到类原型中MyClass.prototype.additionalMethod=函数(){console.log(this.publicVariable);};var myInstance=新建MyClass();myInstance.publicMethod();//“公共价值”myInstance.additionalMethod();//“公共价值”myInstance.privilegedMethod();//“私人价值”MyClass.staticMethod();//“静态值”

如果你想使用原型,那么有一种方法

var p = function Person() {
    this.x = 10;
    this.y = 20;
}
p.prototype.counter = 0;
var person1 = new p();
person1.prototype = p.prototype;
console.log(person1.counter);
person1.prototype.counter++;
var person2 = new p();
person2.prototype = p.prototype;
console.log(person2.counter);
console.log(person1.counter);

这样做,您将能够从任何实例访问计数器变量,并且属性中的任何更改都将立即反映出来!!

如果您正在使用新的类语法,那么现在可以执行以下操作:

类MyClass{静态获取myStaticVariable(){返回“一些静态变量”;}}console.log(MyClass.myStaticVariable);aMyClass=新建MyClass();console.log(aMyClass.myStaticVariable,“未定义”);

这有效地在JavaScript中创建了一个静态变量。

您可以在JavaScript中创建一个静态变量,如下所示。这里count是静态变量。

var Person = function(name) {
  this.name = name;
  // first time Person.count is undefined, so it is initialized with 1
  // next time the function is called, the value of count is incremented by 1
  Person.count = Person.count ? Person.count + 1 : 1;
}

var p1 = new Person('User p1');
console.log(p1.constructor.count);   // prints 1
var p2 = new Person('User p2');
console.log(p2.constructor.count);   // prints 2

您可以使用Person函数或任何实例为静态变量赋值:

// set static variable using instance of Person
p1.constructor.count = 10;         // this change is seen in all the instances of Person
console.log(p2.constructor.count); // prints 10

// set static variable using Person
Person.count = 20;
console.log(p1.constructor.count); // prints 20

试试这个:

如果我们定义一个属性并重写其getter和setter以使用Function Object属性,那么理论上可以在javascript中使用一个静态变量

例如:

函数Animal(){if(isNaN(this.totalAnimalCount)){this.totalAnimalCount=0;}this.totalAnimationCount++;};Object.defineProperty(动画原型,“totalAnimalCount”{获取:函数(){return Animal['totalAnimalCount'];},集合:函数(val){动物['totalAnimalCount']=val;}});var cat=新动画();console.log(cat.totalAnimationCount)//将产生1var dog=新动画();console.log(cat.totalAnimationCount)//将产生2等。