Объявление константы прототипа 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);