代码之家  ›  专栏  ›  技术社区  ›  Rajat

JavaScript中的静态变量

  •  641
  • Rajat  · 技术社区  · 16 年前

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

    38 回复  |  直到 9 年前
        1
  •  925
  •   Christian C. Salvadó    6 年前

    (像java、C++或C语言) 我假设您正在尝试创建一个与“类型”关联的变量或方法,但不与实例关联。

    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将函数视为 first-class objects

    更新: ES6引入了 declare classes class 关键词。它超越了现有的基于原型的继承。

    static keyword 允许您在类中轻松定义静态属性或方法。

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

    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"
        2
  •  558
  •   KęstutisV Taylor Campbell    12 年前

    例如,引用(现已消失)文章中给出的示例 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);
    }
    

    这可能是一个比用全局变量争论全局名称空间更好的解决方案。


    这是另一个可能的解决方案,基于闭包: 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.
    

    这会得到相同的结果——除了这次返回递增的值,而不是显示。

        3
  •  104
  •   Chris    13 年前

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

    var incr = (function () {
        var i = 1;
    
        return function () {
            return i++;
        }
    })();
    
    incr(); // returns 1
    incr(); // returns 2
    
        4
  •  41
  •   Matt    6 年前

    this post 最能描述它,所以我想与您分享。

    下面是从中提取的一些代码,我已经对其进行了修改,以获得一个完整的示例,希望能够为社区带来好处,因为它可以用作类的设计模板。

    它也

    function Podcast() {
    
        // private variables
        var _somePrivateVariable = 123;
    
        // object properties (read/write)
        this.title = 'Astronomy Cast';
        this.description = 'A fact-based journey through the galaxy.';
        this.link = 'http://www.astronomycast.com';
    
        // for read access to _somePrivateVariable via immutableProp 
        this.immutableProp = function() {
            return _somePrivateVariable;
        }
    
        // object function
        this.toString = function() {
           return 'Title: ' + this.title;
        }
    };
    
    // static property
    Podcast.FILE_EXTENSION = 'mp3';
    // static function
    Podcast.download = function(podcast) {
        console.log('Downloading ' + podcast + ' ...');
    };
    

    根据该示例,您可以访问

    // access static properties/functions
    console.log(Podcast.FILE_EXTENSION);   // 'mp3'
    Podcast.download('Astronomy cast');    // 'Downloading Astronomy cast ...'
    

    对象属性/函数 简而言之:

    // access object properties/functions
    var podcast = new Podcast();
    podcast.title = 'The Simpsons';
    console.log(podcast.toString());       // Title: The Simpsons
    console.log(podcast.immutableProp());  // 123
    

    closure :

    你甚至可以定义 接球手和接球手 d y 私有变量在构造函数外部不可见):

    // getters and setters
    var d = Date.prototype;
    Object.defineProperty(d, "year", {
        get: function() {return this.getFullYear() },
        set: function(y) { this.setFullYear(y) }
    });
    

    它定义了属性 d.year get 和 set 函数-如果未指定 设置 ,则该属性为只读且无法修改(请注意,如果尝试设置该属性,则不会出现错误,但不会产生任何效果)。每个属性都有属性 writable configurable (声明后允许更改)和 enumerable (允许将其用作枚举数),这是默认值 false defineProperty 在第三个参数中,例如。 enumerable: true .

    以下语法同样有效:

    // getters and setters - alternative syntax
    var obj = { a: 7, 
                get b() {return this.a + 1;}, 
                set c(x) {this.a = x / 2}
            };
    

    a ,一个只读属性 b 和只写属性 c ,通过哪个属性 可以访问。

    用法:

    console.log(obj.a); console.log(obj.b); // output: 7, 8
    obj.c=40;
    console.log(obj.a); console.log(obj.b); // output: 20, 21
    

    笔记:

    以避免意外行为,以免您忘记 new 关键字,我建议您在函数中添加以下内容 Podcast :

    // instantiation helper
    function Podcast() {
        if(false === (this instanceof Podcast)) {
            return new Podcast();
        }
    // [... same as above ...]
    };
    

    现在,以下两个实例化将按预期工作:

    var podcast = new Podcast(); // normal usage, still allowed
    var podcast = Podcast();     // you can omit the new keyword because of the helper
    

    “new”语句创建一个新对象并复制所有属性和方法,即。

    var a=new Podcast();
    var b=new Podcast();
    a.title="a"; b.title="An "+b.title;
    console.log(a.title); // "a"
    console.log(b.title); // "An Astronomy Cast"
    

    在某些情况下,使用 return 构造函数中的语句 返回类内部依赖但需要公开的自定义对象保护函数。本系列文章的第2章(对象)对此作了进一步解释。

    和 播客 A. B 有人举过例子吗?在这种情况下,请使用 .prototype 详情如下:

    Podcast.prototype.titleAndLink = function() {
        return this.title + " [" + this.link + "]";
    };
    

    现在打电话 A. 和 再一次:

    console.log(a.titleAndLink()); // "a [http://www.astronomycast.com]"
    console.log(b.titleAndLink()); // "An Astronomy Cast [http://www.astronomycast.com]"
    

    here . 如果你想继承更多的遗产,我建议你 this .


    这个 article series 我上面提到的是 强烈推荐

    1. 功能
    2. 原型
    3. 在构造函数上强制执行新的
    4. 静态特性和方法

    笔记 那 automatic semicolon insertion JavaScript的“特性”(如6所述)通常会导致代码中出现奇怪的问题。因此,我宁愿将其视为一个bug,而不是一个特性。

    如果你想读更多, here MSDN文章 关于这些主题,这里描述的一些主题提供了更多的细节。

    是什么 此外(也涵盖上述主题)还有来自 MDN JavaScript Guide

    如果你想知道如何 仿效c# out (例如 DateTime.TryParse(str, out result) )在JavaScript中,您可以找到 sample code here.


    你们这些 (它没有JavaScript控制台,除非您使用 并打开控制台选项卡)可能会发现以下代码段很有用。它允许您使用 console.log(msg); 如上面示例中所用。只需将其插入到 作用

    let console = { log: function(msg) {  
      let canvas = document.getElementById("log"), br = canvas.innerHTML==="" ? "" : "<br/>";
      canvas.innerHTML += (br + (msg || "").toString());
    }};
    
    console.log('For details, see the explaining text');
    
    function Podcast() {
    
      // with this, you can instantiate without new (see description in text)
      if (false === (this instanceof Podcast)) {
        return new Podcast();
      }
    
      // private variables
      var _somePrivateVariable = 123;
    
      // object properties
      this.title = 'Astronomy Cast';
      this.description = 'A fact-based journey through the galaxy.';
      this.link = 'http://www.astronomycast.com';
    
      this.immutableProp = function() {
        return _somePrivateVariable;
      }
    
      // object function
      this.toString = function() {
        return 'Title: ' + this.title;
      }
    };
    
    // static property
    Podcast.FILE_EXTENSION = 'mp3';
    // static function
    Podcast.download = function(podcast) {
      console.log('Downloading ' + podcast + ' ...');
    };
    
    
    // access static properties/functions
    Podcast.FILE_EXTENSION; // 'mp3'
    Podcast.download('Astronomy cast'); // 'Downloading Astronomy cast ...'
    
    // access object properties/functions
    var podcast = new Podcast();
    podcast.title = 'The Simpsons';
    console.log(podcast.toString()); // Title: The Simpsons
    console.log(podcast.immutableProp()); // 123
    
    // getters and setters
    var d = Date.prototype;
    Object.defineProperty(d, "year", {
      get: function() {
        return this.getFullYear()
      },
      set: function(y) {
        this.setFullYear(y)
      }
    });
    
    // getters and setters - alternative syntax
    var obj = {
      a: 7,
      get b() {
        return this.a + 1;
      },
      set c(x) {
        this.a = x / 2
      }
    };
    
    // usage:
    console.log(obj.a); console.log(obj.b); // output: 7, 8
    obj.c=40;
    console.log(obj.a); console.log(obj.b); // output: 20, 21
    
    var a=new Podcast();
    var b=new Podcast();
    a.title="a"; b.title="An "+b.title;
    console.log(a.title); // "a"
    console.log(b.title); // "An Astronomy Cast"
    
    Podcast.prototype.titleAndLink = function() {
        return this.title + " [" + this.link + "]";
    };
        
    console.log(a.titleAndLink()); // "a [http://www.astronomycast.com]"
    console.log(b.titleAndLink()); // "An Astronomy Cast [http://www.astronomycast.com]"
    <div id="log"></div>

    • 您可以找到一些关于JavaScript编程的好提示、提示和建议 here (JavaScript best practices) there ('var' versus 'let') . 也推荐这篇文章 about implicit typecasts (coercion)

    • 使用类并将它们编译成JavaScript的一种方便方法是 打字稿。 Here is a playground 在那里你可以找到一些例子来说明它是如何工作的。 我特别推荐在组合框中选择“使用类”、“使用继承”和“使用泛型”的例子,这些都是可以在JavaScript中立即使用的好模板。Typescript与 Angular.

    • 达到 封装 对于JavaScript中的局部变量、函数等,我建议使用如下模式(JQuery使用相同的技术):

    <html>
    <head></head>
    <body><script>
        'use strict';
        // module pattern (self invoked function)
        const myModule = (function(context) { 
        // to allow replacement of the function, use 'var' otherwise keep 'const'
    
          // put variables and function with local module scope here:
          var print = function(str) {
            if (str !== undefined) context.document.write(str);
            context.document.write("<br/><br/>");
            return;
          }
          // ... more variables ...
    
          // main method
          var _main = function(title) {
    
            if (title !== undefined) print(title);
            print("<b>last modified:&nbsp;</b>" + context.document.lastModified + "<br/>");        
            // ... more code ...
          }
    
          // public methods
          return {
            Main: _main
            // ... more public methods, properties ...
          };
    
        })(this);
    
        // use module
        myModule.Main("<b>Module demo</b>");
    </script></body>
    </html>

    *.js 文件这只是内联编写,以保持示例简短。

    described in more detail here .

        5
  •  39
  •   gpilotino    16 年前

    您可以使用arguments.callee存储“静态”变量(这在匿名函数中也很有用):

    function () {
      arguments.callee.myStaticVar = arguments.callee.myStaticVar || 1;
      arguments.callee.myStaticVar++;
      alert(arguments.callee.myStaticVar);
    }
    
        6
  •  31
  •   Max Heiber    8 年前

    ECMAScript 6 ,您可以使用 static

    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
    

    //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
    

    可以指定给的属性 Foo 因为在JavaScript中,函数是对象。

        7
  •  29
  •   jim_zike_huang    14 年前
    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();
    
        8
  •  16
  •   Benoit Garret    14 年前

    以下示例和解释来自Nicholas Zakas的《面向Web开发人员的专业JavaScript第二版》。这是我一直在寻找的答案,所以我认为在这里添加它会有所帮助。

    (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
    

    Person 本例中的构造函数和 getName() 和 setName() setName() 在一个实例上影响所有其他实例。使命感 setName() 或者创造一个新的 人

        9
  •  15
  •   Automatico    9 年前

    如果您正在使用新的 class syntax 然后,您现在可以执行以下操作:

        class MyClass {
          static get myStaticVariable() {
            return "some static variable";
          }
        }
    
        console.log(MyClass.myStaticVariable);
    
        aMyClass = new MyClass();
        console.log(aMyClass.myStaticVariable, "is undefined");

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

        10
  •  8
  •   Hemant    13 年前

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

    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;
    
        11
  •  8
  •   COil    9 年前

    关于 class

    下面是一个演示如何创建静态变量的示例 staticVar ClassName var

    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
    

    为了访问静态变量,我们使用 .constructor 属性,该属性返回对创建类的对象构造函数的引用。

    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
    
        12
  •  7
  •   funroll    11 年前

    还有其他类似的答案,但没有一个能吸引我。以下是我最终得到的结果:

    var nextCounter = (function () {
      var counter = 0;
      return function() {
        var temp = counter;
        counter += 1;
        return temp;
      };
    })();
    
        13
  •  7
  •   Dimitris Fasarakis Hilliard    8 年前

    除其他外,目前还有一份草案( stage-2 proposal ECMA Proposals 介绍 static 类中的字段。( private fields were considered )

    使用提案中的示例,建议

    class CustomDate {
      // ...
      static epoch = new CustomDate(0);
    }
    

    class CustomDate {
      // ...
    }
    CustomDate.epoch = new CustomDate(0);
    

    然后,您可以通过 CustomDate.epoch .

    你可以随时了解新的提案 proposal-static-class-features .


    transform class properties 你可以使用的插件。此外,尽管仍在进行中, V8 is implementing it .

        14
  •  6
  •   Sнаđошƒаӽ    10 年前

    您可以像下面这样在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
    
        15
  •  5
  •   JoolzCheat    14 年前

    var my_id = 123;
    

    将变量替换为以下内容:

    Object.defineProperty(window, 'my_id', {
        get: function() {
                return 123;
            },
        configurable : false,
        enumerable : false
    });
    
        16
  •  5
  •   GetFree    8 年前

    有4种方法可以在Javascript中模拟函数局部静态变量。

    方法1:使用函数对象属性 (旧浏览器支持)

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

    (旧浏览器支持)

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

    方法3:使用闭包,变体2

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

    方法4:使用闭包,变体3 (需要对EcmaScript 2015的支持)

    {
        let staticVar = 0 ;
        function someFunc4(){
            alert(++staticVar) ;
        }
    }
    
    someFunc4() ; //prints 1
    someFunc4() ; //prints 2
    someFunc4() ; //prints 3
    
        17
  •  4
  •   Andrew Hare    16 年前

    JavaScript中最接近静态变量的是全局变量——这只是在函数或对象文本范围之外声明的变量:

    var thisIsGlobal = 1;
    
    function foo() {
        var thisIsNot = 2;
    }
    

    您可以做的另一件事是在对象文本中存储全局变量,如下所示:

    var foo = { bar : 1 }
    

    然后像这样访问变量: foo.bar .

        18
  •  4
  •   Luca Reghellin    12 年前

    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
    

    好的,另一种方法来看看这些方面的最佳实践,就是看看coffeescript是如何翻译这些概念的。

    #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);
    
        19
  •  4
  •   Neeraj Kumar Ankit Sanghavi    7 年前

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

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

        20
  •  2
  •   Aran-Fey Kevin    8 年前

    在JavaScript中,变量是 静止的 默认情况下。 实例 :

    var x = 0;
    
    function draw() {
        alert(x); //
        x+=1;
    }
    
    setInterval(draw, 1000);
    


    它将打印1、2、3等等

        21
  •  1
  •   Yash    8 年前

    Function Hoisting, declarations & expressions

    • 使用函数构造函数创建的函数不会为其创建上下文创建闭包;它们始终在全局范围内创建。

        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 -闭包的副本与保留的数据一起运行。

    • JavaScript中的闭包类似于由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函数类 Object.defineProperty ( O, P, Attributes )

    这个 Object.defineProperty() 方法直接在对象上定义新属性,或修改对象上的现有属性,然后返回该对象。

    使用创建了一些方法 `` ,以便每一次都能轻松理解函数类。

    '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;
    }
    

    下面的代码片段是关于每个实例都有自己的实例成员和公共静态成员副本的测试。

    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 调用直接在类上进行,不能在类的实例上调用。但是您可以从实例内部实现对静态成员的调用。

    使用语法:

       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类:ES2015类是对基于原型的OO模式的简单补充。使用一个方便的声明形式可以使类模式更易于使用,并鼓励互操作性。类支持基于原型的继承、超级调用、实例和静态方法以及构造函数。

    Example 参考我以前的帖子。

        22
  •  1
  •   vkarpov15    6 年前

    你可以定义 static functions in JavaScript static 关键词:

    class MyClass {
      static myStaticFunction() {
        return 42;
      }
    }
    
    MyClass.myStaticFunction(); // 42
    

    在撰写本文时,仍然无法在类中定义静态属性(函数除外)。静态属性仍然是一个问题 Stage 3 proposal

    class MyClass {}
    
    MyClass.myStaticProperty = 42;
    
    MyClass.myStaticProperty; // 42
    

    all inherited classes share the same copy of the object .

        23
  •  1
  •   AKUMA no ONI    5 年前

    2021年更新

    在2021年,您只需使用 static

    TC39移动了服务器 STATIC 关键词到存在 截至2021年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
    }
    
    
    Example above was taken from the TC39 Repository, Static-Fields


    To read more about the implementation of this new JS language feature (CLICK HERE).
    To read more about the feature itself, as well as seeing examples that demonstarte the syntax used for static fields (CLICK HERE).
        24
  •  0
  •   Bostone    16 年前

        25
  •  0
  •   Todd L    12 年前

    在使用jQuery的MVC网站上工作时,我希望确保某些事件处理程序中的AJAX操作只能在前一个请求完成后执行。我使用“静态”jqXHR对象变量来实现这一点。

    给定以下按钮:

    <button type="button" onclick="ajaxAction(this, { url: '/SomeController/SomeAction' })">Action!</button>
    

    我通常使用这样的生活作为我的点击处理程序:

    var ajaxAction = (function (jqXHR) {
        return function (sender, args) {
            if (!jqXHR || jqXHR.readyState == 0 || jqXHR.readyState == 4) {
                jqXHR = $.ajax({
                    url: args.url,
                    type: 'POST',
                    contentType: 'application/json',
                    data: JSON.stringify($(sender).closest('form').serialize()),
                    success: function (data) {
                        // Do something here with the data.
                    }
                });
            }
        };
    })(null);
    
        26
  •  0
  •   charlie    12 年前

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

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

    执行此操作,您将能够从任何实例访问计数器变量,并且属性中的任何更改都将立即反映!!

        27
  •  0
  •   lindsaymacvean    10 年前

    面向对象编程实际上有两种不同的风格,一种是“基于类”(C++、C#、Java等),另一种是“原型”(Javascript)。在基于类的语言中,“静态属性”应该与类关联,而不是与实例化的对象关联。这个概念实际上在Javascript这样的原型语言中更直观,因为您只需将属性指定为父原型的值,就像这样。

    function MyObject() {};
    MyObject.prototype.staticAttribute = "some value";
    

    然后从这个构造函数实例化的每个对象访问它,就像这样。。。

    var childObject1 = new MyObject(); // Instantiate a child object
    var childObject2 = new MyObject(); // Instantiate another child object
    console.log(childObject.staticAttribute); // Access the static Attribute from child 1
    console.log(childObject.staticAttribute); // Access the static Attribute from child 2
    

    MyObject.prototype.staticAttribute

    首先确保通过将构造函数封装在另一个函数(如jqueryready方法)中,将其从全局命名空间中隐藏

     $(document).ready(function () {
        function MyObject() {
            // some constructor instructions
        };
        MyObject.prototype.staticAttribute = "some value";
        var childObject = new MyObject(); // instantiate child object
        console.log(childObject.staticAttribute); // test attribute
    });
    

    第二,也是最后一点,即使您这样做,属性仍然可以从您自己脚本的任何其他部分编辑,因此可能是代码中的错误将属性写入其中一个子对象,并将其与父原型分离,因此,如果更改父属性,它将不再级联并更改子对象的静态属性。 See this jsfiddle. 在不同的情况下,我们可以 Object.freeze(obj)

    在我看来,基于类的“静态属性”概念和这个Javascript实现之间似乎没有完美的相似之处。因此,我认为从长远来看,使用一种更为Javascript友好的不同代码模式可能会更好。例如一个中央数据存储或缓存,甚至一个专用的helper对象来保存所有必需的静态变量。

        28
  •  0
  •   danielson317    10 年前

    我没有在任何答案中看到这个想法,所以只是把它添加到列表中。如果它是重复的,请让我知道,我会删除它并更新另一个。

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

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

    然后我需要几个全局辅助函数

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

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

    这当然是一个全局的,而不是静态的,但因为它在每次页面加载时都会重新初始化,所以它实现了相同的目的。

        29
  •  0
  •   drneel windsurf88    10 年前

    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
    
        30
  •  0
  •   Martin Wantke    9 年前

    对于私有静态变量,我发现如下方法:

    function Class()
    {
    }
    
    Class.prototype = new function()
    {
        _privateStatic = 1;
        this.get = function() { return _privateStatic; }
        this.inc = function() { _privateStatic++; }
    };
    
    var o1 = new Class();
    var o2 = new Class();
    
    o1.inc();
    
    console.log(o1.get());
    console.log(o2.get()); // 2
    
    推荐文章