Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript prototype constant declaration

Tags:

javascript

oop

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?

like image 376
Husman Avatar asked Jul 25 '13 13:07

Husman


People also ask

How do you declare constants in JavaScript?

Constants are block-scoped, much like variables declared using the let keyword. The value of a constant can't be changed through reassignment (i.e. by using the assignment operator), and it can't be redeclared (i.e. through a variable declaration).

Is __ proto __ deprecated?

__proto__ is considered outdated and somewhat deprecated (moved to the so-called “Annex B” of the JavaScript standard, meant for browsers only). The modern methods to get/set a prototype are: Object.

What is difference between __ proto __ and prototype?

prototype is a property of a Function object. It is the prototype of objects constructed by that function. __proto__ is an internal property of an object, pointing to its prototype. Current standards provide an equivalent Object.

What does __ proto __ mean in JavaScript?

Description. The __proto__ getter function exposes the value of the internal [[Prototype]] of an object. For objects created using an object literal, this value is Object. prototype . For objects created using array literals, this value is Array.


2 Answers

Using 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).

like image 143
apsillers Avatar answered Oct 05 '22 23:10

apsillers


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.

like image 20
Dennis Avatar answered Oct 05 '22 23:10

Dennis