Где объявить константы класса? - PullRequest
21 голосов
/ 25 января 2011

Я использую учеников для хранения констант. E.g.:

function Foo() {
}

Foo.CONSTANT1 = 1;
Foo.CONSTANT2 = 2;

Это прекрасно работает, за исключением того, что кажется немного неорганизованным, когда весь код, специфичный для Foo, находится в глобальной области видимости. Поэтому я подумал о том, чтобы переместить объявление константы внутрь объявления Foo(), но разве этот код не будет выполняться каждый раз при создании Foo?

Я пришел из Java, где все заключено в тело класса, поэтому я думаю, что в JavaScript может быть что-то похожее на это или какая-то работа вокруг, имитирующая это.

Ответы [ 9 ]

30 голосов
/ 25 января 2011

Все, что вы делаете в своем коде, - это добавление свойства с именем CONSTANT со значением 1 к объекту Function с именем Foo, а затем немедленно перезаписывает его значением 2.

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

Ни одно из свойств, которые вы добавляете к Foo, никогда не будет выполнено. Они просто хранятся в этом пространстве имен.

Может быть, вы хотите создать прототип какого-либо свойства на Foo?

function Foo() {
}

Foo.prototype.CONSTANT1 = 1;
Foo.prototype.CONSTANT2 = 2;

Не совсем то, что вы после того, как.

14 голосов
/ 16 апреля 2013

Вы должны сделать свои константы такими, как вы сказали:

function Foo() {
}

Foo.CONSTANT1 = 1;
Foo.CONSTANT2 = 2;

И вы получите такой доступ:

Foo.CONSTANT1;

или

anInstanceOfFoo.__proto__.constructor.CONSTANT1;

Все остальные решениядругая часть памяти, когда вы создаете другой объект, так что это не константа. Вы не должны делать это:

Foo.prototype.CONSTANT1 = 1;
3 голосов
/ 04 февраля 2012

Если вы используете jQuery, вы можете использовать функцию $ .extend для категоризации всего.

var MyClass = $.extend(function() {
        $.extend(this, {
            parameter: 'param',
            func: function() {
                console.log(this.parameter);
            }
        });
        // some code to do at construction time
    }, {
        CONST: 'const'
    }
);
var a = new MyClass();
var b = new MyClass();
b.parameter = MyClass.CONST;
a.func();       // console: param
b.func();       // console: const
3 голосов
/ 04 октября 2011

ЕСЛИ константы должны использоваться только внутри объекта:

function Foo() {
    var CONSTANT1 = 1,CONSTANT2 = 2;
}

Если нет, сделайте это следующим образом:

function Foo(){
    this.CONSTANT1=1;
    this.CONSTANT2=2;
}

Это намного более читабельно и легче работатьиз того, что делает функция.

2 голосов
/ 17 мая 2016

Во-первых, я рекомендую переместить объявление класса в IIFE .Это очищает код, делает его более автономным и позволяет использовать локальные переменные, не загрязняя глобальное пространство имен.Ваш код становится:

var Foo = (function() {
  function Foo() {
  }

  Foo.CONSTANT1 = 1;
  Foo.CONSTANT2 = 2;

  return Foo;
})();

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

var output = document.getElementById("output");

var Foo = (function() {
  function Foo() {
  }

  Foo.CONSTANT1 = 1;
  Foo.CONSTANT2 = 2;

  return Foo;
})();

Foo.CONSTANT1 = "I'm not very constant";

output.innerHTML = Foo.CONSTANT1;
<div id="output"></div>

Лучшее решение, которое я нашел, - это определение свойств только для чтения для доступа к константам вне класса.

var output = document.getElementById("output");

var Foo = (function() {
  const CONSTANT1 = "I'm very constant";

  function Foo() {
  }

  Object.defineProperty(Foo, "CONSTANT1", {
    get: function() {
      return CONSTANT1;
    },
  });

  return Foo;
})();

Foo.CONSTANT1 = "some other value";

output.innerHTML = Foo.CONSTANT1;
<div id="output"></div>

(Технически вы можете отказаться от оператора const CONSTANT1 и просто вернуть значение из определения свойства, но я предпочитаю это, потому что это упрощает просмотр всехконстанты с первого взгляда.)

2 голосов
/ 25 января 2011

то, что вы делаете, прекрасно (при условии, что вы понимаете, что ваш пример просто устанавливает одно и то же свойство дважды);это эквивалент статической переменной в Java (как можно ближе, по крайней мере, без большой работы).Кроме того, он не является полностью глобальным, поскольку он находится в функции конструктора, он фактически помещается в пространство имен вашего «класса».

1 голос
/ 15 декабря 2012

Также с пространствами имен

var Constants = {
    Const1: function () {
        Const1.prototype.CONSTANT1 = 1;
        Const1.prototype.CONSTANT2 = 2;
    },

    Const2: function () {
        Const2.prototype.CONSTANT3 = 4;
        Const2.prototype.CONSTANT4 = 3;
    }
};
1 голос
/ 25 января 2011

Ваши константы - это просто переменные, и вы не будете знать, попытаетесь ли вы случайно перезаписать их. Также обратите внимание, что в Javascript отсутствует понятие «класс».

Я бы предложил вам создать функции, которые возвращают значения, которые вам нужны постоянные.

Чтобы почувствовать вкус Javascript, найдите Javascript: Хорошие части и изучите идиоматические способы. Javascript очень отличается от Java.

0 голосов
/ 09 июля 2015

Вы сказали, что пришли из Java - почему бы вам не сохранить этот класс в 1 файле и константы в конце файла. Вот что я использую:

имя файла: PopupWindow.js

function PopupWindow() {
    //private class memebers
    var popup, lightbox;
    //public class memeber or method (it is the same in JS if I am right)
    this.myfuncOrmyMemeber = function() {};
}

//static variable
PopupWindow._instance = null;
//same thing again with constant-like name (you can't have "final" in JS if I am right, so it is not immutable constant but its close enough ;) - just remember not to set varibales with BIG_LETTERS :D)
PopupWindow.MY_CONSTANT = 1;
//yea, and same thing with static methods again
PopupWindow._getInstance = function() {};

Так что единственное отличие - это положение статичного материала. Он не выровнен внутри фигурных скобок класса, но кого это волнует, его всегда нажимают ctrl + click в IDE (или я использую ctr + l, чтобы показать все методы класса - IntellijIdea может сделать это в JS, не знаю, как в других IDE), так что вы не собираетесь ищите это своим глазом;)

Да, и я использую _ до статического метода - он не нужен, я не знаю, почему я начал это делать:)

...