Статические переменные в JavaScript - PullRequest
662 голосов
/ 08 октября 2009

Как я могу создать статические переменные в Javascript?

Ответы [ 38 ]

1 голос
/ 30 августа 2018

Резюме:

В ES6 / ES 2015 ключевое слово class было введено с сопровождающим ключевым словом static. Имейте в виду, что это синтаксический сахар по сравнению с прототипной моделью наследования, которую воплощает javavscript. Ключевое слово static работает следующим образом:

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

}

В chrome devtools мы можем визуализировать это:

static variables javascript

Теперь мы создали функцию static, которую мы можем выполнить с помощью ClassName.method()

1 голос
/ 31 марта 2016

В JavaScript нет термина или ключевого слова static, но мы можем поместить такие данные непосредственно в объект функции (как в любом другом объекте).

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
1 голос
/ 26 апреля 2018

Существует 4 способа эмулировать функционально-локальные статические переменные в Javascript.

Способ 1. Использование свойств объекта функции (поддерживается в старых браузерах)

function someFunc1(){
    if( !('staticVar' in someFunc1) )
        someFunc1.staticVar = 0 ;
    alert(++someFunc1.staticVar) ;
}

someFunc1() ; //prints 1
someFunc1() ; //prints 2
someFunc1() ; //prints 3

Способ 2. Использование замыкания, вариант 1 (поддерживается в старых браузерах)

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
0 голосов
/ 30 августа 2017

Я часто использую статические переменные функции, и очень жаль, что в 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 ().

Затем вы можете сделать:

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

  if (_s.v1==3) { ++_s.v1; _s.v2(_s.v1); }
} 

Сравнивая это с IIFE, который является другим правильным ответом, он имеет недостаток, заключающийся в добавлении одного присваивания и одного if при каждом вызове функции и добавлении члена функции _statics к функции, однако есть несколько преимуществ: аргументы находятся вверху, а не во внутренней функции, использование «статического» во внутреннем коде функции явно с «_s». префикс, и в целом проще смотреть и понимать.

0 голосов
/ 08 октября 2009

В Javascript нет такой вещи как статическая переменная. Этот язык ориентирован на объекты на основе прототипов, поэтому нет никаких классов, но есть прототипы, из которых объекты «копируют» себя.

Вы можете имитировать их с помощью глобальных переменных или прототипирования (добавляя свойство к прототипу):

function circle(){
}
circle.prototype.pi=3.14159
0 голосов
/ 12 января 2013
{
   var statvar = 0;
   function f_counter()
   {
      var nonstatvar = 0;
      nonstatvar ++;
      statvar ++;
      return statvar + " , " + nonstatvar;
   }
}
alert(f_counter());
alert(f_counter());
alert(f_counter());
alert(f_counter());

Это просто еще один способ получить статическую переменную, которую я где-то выучил.

0 голосов
/ 13 марта 2014

Работая с веб-сайтами MVC, использующими jQuery, я хочу убедиться, что действия AJAX в определенных обработчиках событий могут выполняться только после завершения предыдущего запроса. Я использую «статическую» переменную объекта jqXHR для достижения этой цели.

Учитывая следующую кнопку:

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

Я обычно использую IIFE, как это для моего обработчика кликов:

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);
0 голосов
/ 08 октября 2009

Переменные уровня окна похожи на статические в том смысле, что вы можете использовать прямую ссылку, и они доступны для всех частей вашего приложения

0 голосов
/ 25 октября 2016

Для частных статических переменных я нашел такой способ:

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
0 голосов
/ 19 марта 2014

Система «Класс»

var Rect = (function(){
    'use strict';
     return {
        instance: function(spec){
            'use strict';
            spec = spec || {};

            /* Private attributes and methods */
            var x = (spec.x === undefined) ? 0 : spec.x,
            y = (spec.x === undefined) ? 0 : spec.x,
            width = (spec.width === undefined) ? 1 : spec.width,
            height = (spec.height === undefined) ? 1 : spec.height;

            /* Public attributes and methods */
            var that = { isSolid: (spec.solid === undefined) ? false : spec.solid };

            that.getX = function(){ return x; };
            that.setX = function(value) { x = value; };

            that.getY = function(){ return y; };
            that.setY = function(value) { y = value; };

            that.getWidth = function(){ return width; };
            that.setWidth = function(value) { width = value; };

            that.getHeight = function(){ return height; };
            that.setHeight = function(value) { height = value; };

            return that;
        },

        copy: function(obj){
            return Rect.instance({ x: obj.getX(), y: obj.getY(), width: obj.getWidth, height: obj.getHeight(), solid: obj.isSolid });
        }
    }
})();
...