Static variables in JavaScript

后端 未结 30 2094
别那么骄傲
别那么骄傲 2020-11-22 01:55

How can I create static variables in Javascript?

相关标签:
30条回答
  • 2020-11-22 02:17

    You do it through an IIFE (immediately invoked function expression):

    var incr = (function () {
        var i = 1;
    
        return function () {
            return i++;
        }
    })();
    
    incr(); // returns 1
    incr(); // returns 2
    
    0 讨论(0)
  • 2020-11-22 02:18

    If you want to use prototype then there is a way

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

    Doing this you will be able to access the counter variable from any instance and any change in the property will be immediately reflected!!

    0 讨论(0)
  • 2020-11-22 02:21

    If you come from a class-based, statically typed object-oriented language (like Java, C++ or C#) I assume that you are trying to create a variable or method associated to a "type" but not to an instance.

    An example using a "classical" approach, with constructor functions maybe could help you to catch the concepts of basic 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 is defined in the MyClass object (which is a function) and has nothing to do with its created instances, JavaScript treats functions as first-class objects, so being an object, you can assign properties to a function.

    UPDATE: ES6 introduced the ability to declare classes through the class keyword. It is syntax sugar over the existing prototype-based inheritance.

    The static keyword allows you to easily define static properties or methods in a class.

    Let's see the above example implemented with ES6 classes:

    class MyClass {
      // class constructor, equivalent to
      // the function body of a constructor
      constructor() {
        const privateVariable = 'private value'; // Private variable at the constructor scope
        this.publicVariable = 'public value'; // Public property
    
        this.privilegedMethod = function() {
          // Public Method with access to the constructor scope variables
          console.log(privateVariable);
        };
      }
    
      // Prototype methods:
      publicMethod() {
        console.log(this.publicVariable);
      }
    
      // Static properties shared by all instances
      static staticProperty = 'static value';
    
      static staticMethod() {
        console.log(this.staticProperty);
      }
    }
    
    // We can add properties to the class prototype
    MyClass.prototype.additionalMethod = function() {
      console.log(this.publicVariable);
    };
    
    var myInstance = new MyClass();
    myInstance.publicMethod();       // "public value"
    myInstance.additionalMethod(); // "public value"
    myInstance.privilegedMethod(); // "private value"
    MyClass.staticMethod();             // "static value"

    0 讨论(0)
  • 2020-11-22 02:25

    There are 4 ways to emulate function-local static variables in Javascript.

    Method 1: Using function object properties (supported in old browsers)

    function someFunc1(){
        if( !('staticVar' in someFunc1) )
            someFunc1.staticVar = 0 ;
        alert(++someFunc1.staticVar) ;
    }
    
    someFunc1() ; //prints 1
    someFunc1() ; //prints 2
    someFunc1() ; //prints 3
    

    Method 2: Using a closure, variant 1 (supported in old browsers)

    var someFunc2 = (function(){
        var staticVar = 0 ;
        return function(){
            alert(++staticVar) ;
        }
    })()
    
    someFunc2() ; //prints 1
    someFunc2() ; //prints 2
    someFunc2() ; //prints 3
    

    Method 3: Using a closure, variant 2 (also supported in old browsers)

    var someFunc3 ;
    with({staticVar:0})
        var someFunc3 = function(){
            alert(++staticVar) ;
        }
    
    someFunc3() ; //prints 1
    someFunc3() ; //prints 2
    someFunc3() ; //prints 3
    

    Method 4: Using a closure, variant 3 (requires support for EcmaScript 2015)

    {
        let staticVar = 0 ;
        function someFunc4(){
            alert(++staticVar) ;
        }
    }
    
    someFunc4() ; //prints 1
    someFunc4() ; //prints 2
    someFunc4() ; //prints 3
    
    0 讨论(0)
  • 2020-11-22 02:28

    You might take advantage of the fact that JS functions are also objects -- which means they can have properties.

    For instance, quoting the example given on the (now vanished) article Static variables in 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);
    }
    

    If you call that function several time, you'll see the counter is being incremented.

    And this is probably a much better solution than poluting the global namespace with a global variable.


    And here is another possible solution, based on a closure : Trick to use static variables in 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.
    

    Which gets you the same kind of result -- except, this time, the incremented value is returned, instead of displayed.

    0 讨论(0)
  • 2020-11-22 02:28

    About the class introduced by ECMAScript 2015. The other answers are not totally clear.

    Here is an example showing how to create a static var staticVar with the ClassName.var synthax:

    class MyClass {
        constructor(val) {
            this.instanceVar = val;
            MyClass.staticVar = 10;
        }
    }
    
    var class1 = new MyClass(1);
    console.log(class1.instanceVar);      // 1
    console.log(class1.constructor.staticVar); // 10
    
    // New instance of MyClass with another value
    var class2 = new MyClass(3);
    console.log(class1.instanceVar);      // 1
    console.log(class2.instanceVar);      // 3
    

    To access the static variable we use the .constructor property that returns a reference to the object constructor function that created the class. We can call it on the two created instances:

    MyClass.staticVar = 11;
    console.log(class1.constructor.staticVar); // 11
    console.log(class2.constructor.staticVar); // 11 <-- yes it's static! :)
    
    MyClass.staticVar = 12;
    console.log(class1.constructor.staticVar); // 12
    console.log(class2.constructor.staticVar); // 12
    
    0 讨论(0)
提交回复
热议问题