Javascript prototype constant declaration

I work with a RESTful API, and my Javascript code makes REST requests using jQuery $ .ajax () call.

I implemented the javascript JavaScript 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, but I decided to add some constants to help decorate the code and improve readability. I have several places in my code where I check xhr.status == 200 or xhr.status == 400, etc.

I can declare class variables as Rest.prototype.STATUS_OK = 200;

But the variable is editable, and I can’t figure out how to make it constant. In my code, for example, I can do this.STATUS_OK = 123; and this will change this variable. I played with the const keyword, with no luck.

I saw this: Where to declare class constants? , but it did not help.

Can someone point me in the right direction how to make these fields a constant literal instead of a variable?

+6
source share
4 answers

Using ECMAScript 5 Object.defineProperty , you can make the 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 these are the default values, simply do:

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

This makes Rest.STATUS_OK yield 200 available, but it will not respond to attempts to override it or delete it. In addition, configurable: false prevent any attempt to override a property and then call defineProperty .

However, this does not work in older browsers that do not support ES5 defineProperty (especially IE8 and below).

+8
source

This is not possible in Javascript. The best thing you could probably do is to create some kind of closure like:

 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 as StatusCode.getOk() === 200 . This will help you not to change these "constants", but again it will be bad for your readability (perhaps this is based on opinions). I would just keep these constants in uppercase to mark them as constants, although they could be changed.

+1
source

You can define statuses as getters, but AFAIK this will not work in IE8 and later.

 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 about getters and setters: http://ejohn.org/blog/javascript-getters-and-setters/

+1
source

Javascript does not have good support for creating immutable constants. Even the const keyword is not recommended, as it does not work in some browsers.

I think the best way to do this is to use Object.freeze :

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

Object.freeze will ignore changes to the Status object. Example:

 Rest.Status.Ok = "foo"; Rest.Status.Ok; //=> "Ok" 

But just work in ECMAScript 5 or higher.

Above, I placed the status in the Status object, I think it is more interesting than prototype , because the prototype is closer to instance methods, properties, etc. And the Status object is considered an enumeration.

0
source

Source: https://habr.com/ru/post/950269/


All Articles