Объявление константы прототипа Javascript

Я работаю с RESTful API,и мой код Javascript делает запросы REST через $jQuery.ajax () вызов.

я реализовал класс Rest javascript, который я покажу ниже (значительно упрощенный):

var Rest = function (baseUrlPath, errorMessageHandler) {
        ...
    };

// Declare HTTP response codes as constants
Rest.prototype.STATUS_OK = 200;
Rest.prototype.STATUS_BAD_REQUEST = 400;

... // other rest methods 

Rest.prototype.post = function (params) {
        $.ajax({
            type: 'POST',
            url: params.url,
            data: params.data,
            dataType: 'json',
            contentType: 'application/json; charset=utf-8',
            beforeSend: this._authorize,
            success: params.success,
            error: params.error || this._getAjaxErrorHandler(params.errorMessage)
        });
        };

... // more rest methods

Rest.prototype.executeScenario = function (scenarioRef) {
        var self = this;

        this.post({
            url: 'myurlgoeshere',
            data: 'mydatagoeshere',
            success: function (data, textStatus, xhr) {
                if (xhr.status == 200) {
                    console.log("everything went ok");
                }
            },
            error: function (xhr, textStatus, errorMsg) {
                // TODO: constants
                if (404 == xhr.status) {
                    self.errorMessageHandler("The scenario does not exist or is not currently queued");
                } else if (403 == xhr.status) {
                    self.errorMessageHandler("You are not allowed to execute scenario: " + scenarioRef.displayName);
                } else if(423 == xhr.status) {
                    self.errorMessageHandler("Scenario: " + scenarioRef.displayName +  " is already in the queue");
                }
            }
        });
    };

код работает, как задумано, но я решил добавить некоторые константы, чтобы помочь украсить и улучшить читаемость кода. У меня есть, например, несколько мест в моем коде, где я проверяю xhr.статус = = 200 или xhr.статус == 400 и так на.

Я могу объявить переменные класса как Rest.prototype.STATUS_OK = 200;

но переменная редактируема, и я не могу придумать, как сделать их постоянными. В моем коде, например, я могу сделать this.STATUS_OK = 123; и это изменит переменную. Я играл с ключевым словом const, без везения.

Я видел это: где объявить константы класса?, но это не сильно помогло.

может ли кто-нибудь указать мне в правильном направлении, как сделать эти поля это константа, а не переменная?

4 ответов


использование ECMAScript 5 Object.defineProperty вы можете сделать значение un-settable:

Object.defineProperty(Rest, "STATUS_OK", {
  enumerable: false,   // optional; if you care about your enumerated keys
  configurable: false,
  writable: false,
  value: 200
});

или, поскольку это значения по умолчанию, просто сделайте:

Object.defineProperty(Rest, "STATUS_OK", { value: 200 });

это делает Rest.STATUS_OK доходность 200 при доступе, но он не будет реагировать на попытки переопределить его или delete его. Более того,configurable: false предотвратит любую попытку переопределить свойство с последующим defineProperty звонок.

однако это не работает в старые браузеры, которые не поддерживают в ES5 это defineProperty (особенно IE8 и ниже).


это будет невозможно в Javascript. Лучшее, что вы могли бы сделать, это создать некоторое закрытие, как материал:

var StatusCode = (function() {
    var STATUS_OK = 200,
        STATUS_BAD_REQUEST = 400;

    return {
        getOk: function() {
            return STATUS_OK;
        },
        getBadRequest: function() {
            return STATUS_BAD_REQUEST;
        }
    }

});

и использовать его как StatusCode.getOk() === 200. Это поможет вам не иметь возможности изменять эти "константы", но снова будет плохо для вашей читаемости (это, вероятно, основано на мнении). Я бы просто сохранил эти константы в верхнем регистре, чтобы отметить их как постоянные, хотя они могут быть изменены.


вы можете определить статусы как геттеры, но AFAIK это не будет работать в IE8 и старше.

var Rest = function (baseUrlPath, errorMessageHandler) {
        this.STATUS_OK = 123; // trying to override.
    };

// Declare HTTP response codes as constants
Rest.prototype = {
    get STATUS_OK(){ return 200; },
    get STATUS_BAD_REQUEST(){ return 400; }
}

var client = new Rest();
console.log( client.STATUS_OK ); // 200!
client.STATUS_OK = 123;
console.log( client.STATUS_OK ); // still 200!

подробнее о геттерах и сеттерах:http://ejohn.org/blog/javascript-getters-and-setters/


Javascript не имеет хорошей поддержки для создания неизменяемых констант. Даже const ключевое слово не рекомендуется, потому что не работает в некоторых браузерах.

Я думаю, что лучший способ сделать это с помощью Object.freeze:

Rest.Status = {};
Rest.Status.Ok = "Ok";
Object.freeze(Rest.Status);