Static variables in JavaScript

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

How can I create static variables in Javascript?

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

    Updated answer:

    In ECMAScript 6, you can create static functions using the static keyword:

    class Foo {
    
      static bar() {return 'I am static.'}
    
    }
    
    //`bar` is a property of the class
    Foo.bar() // returns 'I am static.'
    
    //`bar` is not a property of instances of the class
    var foo = new Foo()
    foo.bar() //-> throws TypeError
    

    ES6 classes don't introduce any new semantics for statics. You can do the same thing in ES5 like this:

    //constructor
    var Foo = function() {}
    
    Foo.bar = function() {
        return 'I am static.'
    }
    
    Foo.bar() // returns 'I am static.'
    
    var foo = new Foo()
    foo.bar() // throws TypeError
    

    You can assign to a property of Foo because in JavaScript functions are objects.

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

    Function's / classes allows only single constructor for its object scope. Function Hoisting, declarations & expressions

    • Functions created with the Function constructor do not create closures to their creation contexts; they always are created in the global scope.

        var functionClass = function ( ) {
              var currentClass = Shape;
              _inherits(currentClass, superClass);
              function functionClass() { superClass.call(this); // Linking with SuperClass Constructor.
                  // Instance Variables list.
                  this.id = id;   return this;
              }
          }(SuperClass)
      

    Closures - closure's copies are function with preserved data.

    • Each closure's copies are created to a function with their own free values or references, Whenever you use function inside another function, a closure is used.
    • A closure in JavaScript is like maintaining a copy of all the local variables of its parent function by the innerFunctions.

        function closureFun( args ) {
              // Local variable that ends up within closure
              var num = args;
              num++;
              return function() { console.log(num); }
          }
          var closure1 = closureFun( 5 );
          var closure2 = closureFun( 777 );
          closure1(); // 5
          closure2(); // 777
          closure2(); // 778
          closure1(); // 6
      

    ES5 Function Classes: uses Object.defineProperty ( O, P, Attributes )

    The Object.defineProperty() method defines a new property directly on an object, or modifies an existing property on an object, and returns the object.

    Created some methods by using ``, So that every once can understand the function classes easily.

    'use strict';
    var Shape = function ( superClass ) {
        var currentClass = Shape;
        _inherits(currentClass, superClass); // Prototype Chain - Extends
    
        function Shape(id) { superClass.call(this); // Linking with SuperClass Constructor.
            // Instance Variables list.
            this.id = id;   return this;
        }
        var staticVariablesJOSN = { "parent_S_V" : 777 };
        staticVariable( currentClass, staticVariablesJOSN );
    
        // Setters, Getters, instanceMethods. [{}, {}];
        var instanceFunctions = [
            {
                key: 'uniqueID',
                get: function get() { return this.id; },
                set: function set(changeVal) { this.id = changeVal; }
            }
        ];
        instanceMethods( currentClass, instanceFunctions );
    
        return currentClass;
    }(Object);
    
    var Rectangle = function ( superClass ) {
        var currentClass = Rectangle;
    
        _inherits(currentClass, superClass); // Prototype Chain - Extends
    
        function Rectangle(id, width, height) { superClass.call(this, id); // Linking with SuperClass Constructor.
    
            this.width = width;
            this.height = height;   return this;
        }
    
        var staticVariablesJOSN = { "_staticVar" : 77777 };
        staticVariable( currentClass, staticVariablesJOSN );
    
        var staticFunctions = [
            {
                key: 'println',
                value: function println() { console.log('Static Method'); }
            }
        ];
        staticMethods(currentClass, staticFunctions);
    
        var instanceFunctions = [
            {
                key: 'setStaticVar',
                value: function setStaticVar(staticVal) {
                    currentClass.parent_S_V = staticVal;
                    console.log('SET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
                }
            }, {
                key: 'getStaticVar',
                value: function getStaticVar() {
                    console.log('GET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
                    return currentClass.parent_S_V;
                }
            }, {
                key: 'area',
                get: function get() {
                    console.log('Area : ', this.width * this.height);
                    return this.width * this.height;
                    }
            }, {
                key: 'globalValue',
                get: function get() {
                    console.log('GET ID : ', currentClass._staticVar);
                    return currentClass._staticVar;
                },
                set: function set(value) {
                    currentClass._staticVar = value;
                    console.log('SET ID : ', currentClass._staticVar);
                }
            }
        ];
        instanceMethods( currentClass, instanceFunctions );
    
        return currentClass;
    }(Shape);
    
    // ===== ES5 Class Conversion Supported Functions =====
    function defineProperties(target, props) {
        console.log(target, ' : ', props);
        for (var i = 0; i < props.length; i++) {
            var descriptor = props[i];
            descriptor.enumerable = descriptor.enumerable || false;
            descriptor.configurable = true;
            if ("value" in descriptor) descriptor.writable = true;
            Object.defineProperty(target, descriptor.key, descriptor);
        }
    }
    function staticMethods( currentClass, staticProps ) {
        defineProperties(currentClass, staticProps);
    };
    function instanceMethods( currentClass, protoProps ) {
        defineProperties(currentClass.prototype, protoProps);
    };
    function staticVariable( currentClass, staticVariales ) {
        // Get Key Set and get its corresponding value.
        // currentClass.key = value;
        for( var prop in staticVariales ) {
            console.log('Keys : Values');
            if( staticVariales.hasOwnProperty( prop ) ) {
                console.log(prop, ' : ', staticVariales[ prop ] );
                currentClass[ prop ] = staticVariales[ prop ];
            }
        }
    };
    function _inherits(subClass, superClass) {
        console.log( subClass, ' : extends : ', superClass );
        if (typeof superClass !== "function" && superClass !== null) {
            throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
        }
        subClass.prototype = Object.create(superClass && superClass.prototype, 
                { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });
        if (superClass)
            Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
    }
    

    Below code snippet is to test about Each instance has their own copy of instance members and common static members.

    var objTest = new Rectangle('Yash_777', 8, 7);
    console.dir(objTest);
    
    var obj1 = new Rectangle('R_1', 50, 20);
    Rectangle.println(); // Static Method
    console.log( obj1 );    // Rectangle {id: "R_1", width: 50, height: 20}
    obj1.area;              // Area :  1000
    obj1.globalValue;       // GET ID :  77777
    obj1.globalValue = 88;  // SET ID :  88
    obj1.globalValue;       // GET ID :  88  
    
    var obj2 = new Rectangle('R_2', 5, 70);
    console.log( obj2 );    // Rectangle {id: "R_2", width: 5, height: 70}
    obj2.area;              // Area :  350    
    obj2.globalValue;       // GET ID :  88
    obj2.globalValue = 999; // SET ID :  999
    obj2.globalValue;       // GET ID :  999
    
    console.log('Static Variable Actions.');
    obj1.globalValue;        // GET ID :  999
    
    console.log('Parent Class Static variables');
    obj1.getStaticVar();    // GET Instance Method Parent Class Static Value :  777
    obj1.setStaticVar(7);   // SET Instance Method Parent Class Static Value :  7
    obj1.getStaticVar();    // GET Instance Method Parent Class Static Value :  7
    

    Static method calls are made directly on the class and are not callable on instances of the class. But you can achieve the calls for static members from inside an instance.

    Using syntax:

       this.constructor.staticfunctionName();
    
    class MyClass {
        constructor() {}
        static staticMethod() {
            console.log('Static Method');
        }
    }
    MyClass.staticVar = 777;
    
    var myInstance = new MyClass();
    // calling from instance
    myInstance.constructor.staticMethod();
    console.log('From Inside Class : ',myInstance.constructor.staticVar);
    
    // calling from class
    MyClass.staticMethod();
    console.log('Class : ', MyClass.staticVar);
    

    ES6 Classes: ES2015 classes are a simple sugar over the prototype-based OO pattern. Having a single convenient declarative form makes class patterns easier to use, and encourages interoperability. Classes support prototype-based inheritance, super calls, instance and static methods and constructors.

    Example: refer my previous post.

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

    There is no such thing as an static variable in Javascript. This language is prototype-based object orientated, so there are no classes, but prototypes from where objects "copy" themselves.

    You may simulate them with global variables or with prototyping (adding a property to the prototype):

    function circle(){
    }
    circle.prototype.pi=3.14159
    
    0 讨论(0)
  • 2020-11-22 02:43
    function Person(){
      if(Person.count == undefined){
        Person.count = 1;
      }
      else{
        Person.count ++;
      }
      console.log(Person.count);
    }
    
    var p1 = new Person();
    var p2 = new Person();
    var p3 = new Person();
    
    0 讨论(0)
  • 2020-11-22 02:44

    The following example and explanation are from the book Professional JavaScript for Web Developers 2nd Edition by Nicholas Zakas. This is the answer I was looking for so I thought it would be helpful to add it here.

    (function () {
        var name = '';
        Person = function (value) {
            name = value;
        };
        Person.prototype.getName = function () {
            return name;
        };
        Person.prototype.setName = function (value) {
            name = value;
        };
    }());
    var person1 = new Person('Nate');
    console.log(person1.getName()); // Nate
    person1.setName('James');
    console.log(person1.getName()); // James
    person1.name = 'Mark';
    console.log(person1.name); // Mark
    console.log(person1.getName()); // James
    var person2 = new Person('Danielle');
    console.log(person1.getName()); // Danielle
    console.log(person2.getName()); // Danielle
    

    The Person constructor in this example has access to the private variable name, as do the getName() and setName() methods. Using this pattern, the name variable becomes static and will be used among all instances. This means calling setName() on one instance affects all other instances. Calling setName() or creating a new Person instance sets the name variable to a new value. This causes all instances to return the same value.

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

    In JavaScript, there is no term or keyword static, but we can put such data directly into function object (like in any other object).

    function f() {
        f.count = ++f.count || 1 // f.count is undefined at first
        alert("Call No " + f.count)
    }
    
    f(); // Call No 1
    
    f(); // Call No 2
    
    0 讨论(0)
提交回复
热议问题