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

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

Ответы [ 38 ]

0 голосов
/ 23 февраля 2016

Вы можете так думать. В <body></body> поместите тег <p id='staticVariable'></p> и установите его visibility: hide.

Конечно, вы можете управлять текстом внутри предыдущего тега с помощью jquery. Практически этот тег становится вашей статической переменной.

0 голосов
/ 12 февраля 2016

Я не видел эту идею ни в одном из ответов, поэтому просто добавил ее в список. Если это дубликат, просто дайте мне знать, и я удалю его и добавлю другой комментарий.

Я создал своего рода супер глобальный на моем сайте. Поскольку у меня есть несколько js-файлов, которые загружаются при каждой загрузке страницы, и десятки других js-файлов, которые загружаются только на некоторых страницах, я поместил все «глобальные» функции в одну глобальную переменную.

Вверху моих первых включенных «глобальных» файлов находится объявление

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

Тогда я делаю несколько глобальных вспомогательных функций

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

Тогда, если мне нужна статическая переменная, я просто сохраняю ее вне области видимости, например, за пределами готового документа или вне вложения поведения. (Я использую jquery, но он должен работать в javascript)

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

Это, конечно, глобальный, а не статический объект, но, поскольку он повторно инициализируется при каждой загрузке страницы, он выполняет ту же цель.

0 голосов
/ 11 ноября 2015

Итак, что я вижу в других ответах, так это в том, что они не отвечают фундаментальным архитектурным требованиям статического атрибута в объектно-ориентированном программировании.

Объектно-ориентированное программирование на самом деле имеет два разных стиля, один из которых «основан на классах» (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, изменение будет каскадно касаться дочерних объектов, которые сразу же наследуют его.

Однако есть несколько «уловок», которые могут существенно подорвать «статическую» природу этого атрибута или просто оставить уязвимость безопасности ...

Сначала убедитесь, что конструктор скрыт из глобального пространства имен, заключив его в другую функцию, такую ​​как метод готовности jQuery

 $(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
});

Во-вторых, и, наконец, даже если вы сделаете это, атрибут все равно будет редактироваться из любой другой части вашего собственного скрипта, поэтому может случиться так, что ошибка в вашем коде записывает поверх атрибута одного из дочерних элементов. Объекты и отсоединяет его от родительского прототипа, поэтому если вы измените родительский атрибут, он больше не будет каскадно и не изменит статический атрибут для дочернего объекта. См. Это jsfiddle. В различных сценариях мы могли бы либо Object.freeze(obj) остановить любые изменения дочернего объекта, либо мы могли бы установить метод setter и getter в конструкторе и получить доступ к замыканию, оба из которых имеют сопутствующие сложности.

Мне кажется, что нет идеального аналога между основанной на классе идеей «статического атрибута» и этой реализацией Javascript. Поэтому я думаю, что в конечном итоге было бы лучше использовать другой шаблон кода, более дружественный к Javascript. Например, центральное хранилище данных или кэш или даже выделенный вспомогательный объект для хранения всех необходимых статических переменных.

0 голосов
/ 09 мая 2014

Если вы хотите использовать прототип, то есть способ

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

Сделав это, вы сможете получить доступ к переменной счетчика из любого экземпляра, и любое изменение в свойстве будет немедленно отражено !!

0 голосов
/ 09 ноября 2016

Попробуйте это:

Если мы определим свойство и переопределим его методы получения и установки для использования свойства объекта функции, то в теории вы можете иметь статическую переменную в javascript

например:

function Animal() {
    if (isNaN(this.totalAnimalCount)) {
        this.totalAnimalCount = 0;
    }
    this.totalAnimalCount++;
};
Object.defineProperty(Animal.prototype, 'totalAnimalCount', {
    get: function() {
        return Animal['totalAnimalCount'];
    },
   set: function(val) {
       Animal['totalAnimalCount'] = val;
   }
});
var cat = new Animal(); 
console.log(cat.totalAnimalCount); //Will produce 1
var dog = new Animal();
console.log(cat.totalAnimalCount); //Will produce 2 and so on.
0 голосов
/ 07 февраля 2017

В JavaScript все является либо примитивным типом, либо объектом. Функции являются объектами & mdash; (пары ключ-значение).

Когда вы создаете функцию, вы создаете два объекта. Один объект, который представляет саму функцию, а другой - прототип функции.

Функция в основном в этом смысле является объектом со свойствами:

function name, 
arguments length 
and the functional prototype.

Итак, где установить статическое свойство: Два места, либо внутри объекта функции, либо внутри объекта-прототипа функции.

Вот фрагмент, который создает этот конец, даже создает экземпляры двух экземпляров, используя ключевое слово new JavaScript.

function C () { // function
  var privateProperty = "42";  
  this.publicProperty = "39";  
  
  this.privateMethod = function(){ 
   console.log(privateProperty);
  };
}

C.prototype.publicMethod = function () {    
  console.log(this.publicProperty);
};

C.prototype.staticPrototypeProperty = "4";
C.staticProperty = "3";


var i1 = new C(); // instance 1
var i2 = new C(); // instance 2

i1.privateMethod();
i1.publicMethod();

console.log(i1.__proto__.staticPrototypeProperty);
i1.__proto__.staticPrototypeProperty = "2";
console.log(i2.__proto__.staticPrototypeProperty);

console.log(i1.__proto__.constructor.staticProperty);
i1.__proto__.constructor.staticProperty = "9";
console.log(i2.__proto__.constructor.staticProperty);

Основная идея заключается в том, что экземпляры i1 и i2 используют одни и те же статические свойства.

0 голосов
/ 15 ноября 2018

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

если я хочу сохранить локальные значения функций, я использую что-то вроде "Local.x", "Local.y", "Local.TempData" и т. Д.! *

Если я хочу сохранить статические значения функций, я использую что-то вроде «Static.o», «Static.Info», «Static.count» и т. Д.! *

[Update2]: тот же метод, но использует подход IIFE!

[Update1]: «Статические» и «Локальные» объекты для функций создаются автоматически с помощью предварительного редактирования скриптов!

0 голосов
/ 15 июля 2014

Я помню закрытия JavaScript, когда вижу это .. Вот как я это делаю ..

        function Increment() {
            var num = 0; // Here num is a private static variable
            return function () {
                return ++num;
            }
        }

        var inc = new Increment();
        console.log(inc());//Prints 1
        console.log(inc());//Prints 2
        console.log(inc());//Prints 3
...