I am working with a RESTful API, and my Javascript code is making REST queries via jQuery's $.ajax() call.
I have implemented a javascript Rest class, which I will show below (greatly simplified):
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");
}
}
});
};
The code works as intended, however I have decided to add some constants to help beautify the code and improve readability. I have for example several places in my code where I am checking for xhr.status == 200 or xhr.status == 400 and so on.
I can declare class variables as Rest.prototype.STATUS_OK = 200;
But variable is editable, and I cannot think of how to make them constant. In my code for example I can do a this.STATUS_OK = 123;
and this will modify the variable. I have played around with the const keyword, with no luck.
i have seen this: Where to declare class constants?, but it was not much help.
Can someone point me in the right direction as to how to make these fields a constant literal instead of a variable?
I am working with a RESTful API, and my Javascript code is making REST queries via jQuery's $.ajax() call.
I have implemented a javascript Rest class, which I will show below (greatly simplified):
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");
}
}
});
};
The code works as intended, however I have decided to add some constants to help beautify the code and improve readability. I have for example several places in my code where I am checking for xhr.status == 200 or xhr.status == 400 and so on.
I can declare class variables as Rest.prototype.STATUS_OK = 200;
But variable is editable, and I cannot think of how to make them constant. In my code for example I can do a this.STATUS_OK = 123;
and this will modify the variable. I have played around with the const keyword, with no luck.
i have seen this: Where to declare class constants?, but it was not much help.
Can someone point me in the right direction as to how to make these fields a constant literal instead of a variable?
Share Improve this question edited May 23, 2017 at 11:54 CommunityBot 11 silver badge asked Jul 25, 2013 at 13:24 HusmanHusman 6,90910 gold badges31 silver badges48 bronze badges 1-
Please notice that "fields" are properties, not variables. For variables you simply could use the
const
keyword where supported. But you would local-scope it anyway :-) – Bergi Commented Jul 25, 2013 at 13:54
4 Answers
Reset to default 13Using ECMAScript 5's Object.defineProperty
you can make a value un-settable:
Object.defineProperty(Rest, "STATUS_OK", {
enumerable: false, // optional; if you care about your enumerated keys
configurable: false,
writable: false,
value: 200
});
Or, since those are the default values, simply do:
Object.defineProperty(Rest, "STATUS_OK", { value: 200 });
This makes Rest.STATUS_OK
yield 200
when accessed, but it will not respond to attempts to redefine it or delete
it. Furthermore, configurable: false
will prevent any attempt to redefine the property with a subsequent defineProperty
call.
However, this doesn't work in older browsers that don't support ES5's defineProperty
(notably IE8 and below).
This will not be possible in Javascript. Best thing you could probably do, is create some closure like stuff:
var StatusCode = (function() {
var STATUS_OK = 200,
STATUS_BAD_REQUEST = 400;
return {
getOk: function() {
return STATUS_OK;
},
getBadRequest: function() {
return STATUS_BAD_REQUEST;
}
}
});
And use it like StatusCode.getOk() === 200
. This would help you to not be able to change those 'constants', but will again be bad for your readability (this is probably opinion based).
I would just keep those constants all uppercase to mark them as constant, although they could be changed.
You could define the statuses as getters, but AFAIK this won't work in IE8 and older.
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!
More on getters and setters: http://ejohn/blog/javascript-getters-and-setters/
Javascript doesn't have a good support to create immutable constants. Even the const keyword isn't remended because doesn't work in some browsers.
I think the best way todo it is using Object.freeze
:
Rest.Status = {};
Rest.Status.Ok = "Ok";
Object.freeze(Rest.Status);
Object.freeze will silent ignore changes in the Status object. By example:
Rest.Status.Ok = "foo";
Rest.Status.Ok; //=> "Ok"
But just work in ECMAScript 5 or above.
Above I have placed the status in a Status
object, I think that it is more interesting than prototype
, because prototype is more close to instance methods, properties etc.
And the Status object seen like a enumeration.