Static variables in JavaScript

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

How can I create static variables in Javascript?

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

    Summary:

    In ES6/ES 2015 the class keyword was introduced with an accompanied static keyword. Keep in mind that this is syntactic sugar over the prototypal inheritance model which javavscript embodies. The static keyword works in the following way for methods:

    class Dog {
    
      static bark () {console.log('woof');}
      // classes are function objects under the hood
      // bark method is located on the Dog function object
      
      makeSound () { console.log('bark'); }
      // makeSound is located on the Dog.prototype object
    
    }
    
    // to create static variables just create a property on the prototype of the class
    Dog.prototype.breed = 'Pitbull';
    // So to define a static property we don't need the `static` keyword.
    
    const fluffy = new Dog();
    const vicky = new Dog();
    console.log(fluffy.breed, vicky.breed);
    
    // changing the static variable changes it on all the objects
    Dog.prototype.breed = 'Terrier';
    console.log(fluffy.breed, vicky.breed);

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

    If you wanted to make a global static variable:

    var my_id = 123;
    

    Replace the variable with the below:

    Object.defineProperty(window, 'my_id', {
        get: function() {
                return 123;
            },
        configurable : false,
        enumerable : false
    });
    
    0 讨论(0)
  • 2020-11-22 02:35

    There's another approach, which solved my requirements after browsing this thread. It depends on exactly what you want to achieve with a "static variable".

    The global property sessionStorage or localStorage allows data to be stored for the life of the session, or for an indefinite longer period until explicitly cleared, respectively. This allows data to be shared among all windows, frames, tab panels, popups etc of your page/app and is much more powerful than a simple "static/global variable" in one code segment.

    It avoids all hassle with the scope, lifetime, semantics, dynamics etc of top-level global variables, ie Window.myglobal. Don't know how efficient it is, but that's not important for modest amounts of data, accessed at modest rates.

    Easily accessed as "sessionStorage.mydata = anything" and retrieved similarly. See "JavaScript: The Definitive Guide, Sixth Edition", David Flanagan, ISBN: 978-0-596-80552-4, Chapter 20, section 20.1. This is easily downloadable as a PDF by simple search, or in your O'Reilly Safaribooks subscription (worth its weight in gold).

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

    I use static function variables a lot and it's a real shame JS doesn't have a built-in mechanism for that. Too often I see code where variables and functions are defined in an outer scope even though they're just used inside one function. This is ugly, error prone and just asking for trouble...

    I came up with the following method:

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

    This adds a 'statics' method to all functions (yes, just relax about it), when called it will add an empty object (_statics) to the function object and return it. If an init function is supplied _statics will be set to init() result.

    You can then do:

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

    Comparing this to an IIFE which is the other correct answer, this has the disadvantage of adding one assignment and one if on every function call and adding a '_statics' member to the function, however there are a few advantages: the arguments are there at the top not in the internal function, using a 'static' in the internal function code is explicit with an '_s.' prefix, and it is overall simpler to look at and understand.

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

    You can create a static variable in JavaScript like this below. Here count is the static variable.

    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
    

    You can assign values to the static variable using either the Person function, or any of the instances:

    // 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
    
    0 讨论(0)
  • 2020-11-22 02:40

    To condense all class concepts here, test this:

    var Test = function() {
      // "super private" variable, accessible only here in constructor. There are no real private variables
      //if as 'private' we intend variables accessible only by the class that defines the member and NOT by child classes
      var test_var = "super private";
    
      //the only way to access the "super private" test_var is from here
      this.privileged = function(){
        console.log(test_var);
      }();
    
      Test.test_var = 'protected';//protected variable: accessible only form inherited methods (prototype) AND child/inherited classes
    
      this.init();
    };//end constructor
    
    Test.test_var = "static";//static variable: accessible everywhere (I mean, even out of prototype, see domready below)
    
    Test.prototype = {
    
     init:function(){
       console.log('in',Test.test_var);
     }
    
    };//end prototype/class
    
    
    //for example:
    $(document).ready(function() {
    
     console.log('out',Test.test_var);
    
     var Jake = function(){}
    
     Jake.prototype = new Test();
    
     Jake.prototype.test = function(){
       console.log('jake', Test.test_var);
     }
    
     var jake = new Jake();
    
     jake.test();//output: "protected"
    
    });//end domready
    

    Well, another way to take a look to best practices in these things, is to just see how coffeescript translates these concepts.

    #this is coffeescript
    class Test
     #static
     @prop = "static"
    
     #instance
     constructor:(prop) ->
       @prop = prop
       console.log(@prop)
    
     t = new Test('inst_prop');
    
     console.log(Test.prop);
    
    
    //this is how the above is translated in plain js by the CS compiler
      Test = (function() {
        Test.prop = "static";
    
        function Test(prop) {
         this.prop = prop;
         console.log(this.prop);
        }
    
        return Test;
    
      })();
    
      t = new Test('inst_prop');
    
      console.log(Test.prop);
    
    0 讨论(0)
提交回复
热议问题