KC Baltz
KC Baltz

Reputation: 1508

Is it a best practice to extract String literals to constants in Javascript?

In Java, I consider it a best practice to replace string literals with a constant variable any time they are used in more than one place and expected to match. For example, if you're going to set a cookie and then later read it back, the name of the cookie should be in a constant so the compiler can help you catch spelling errors, not to mention allowing you to have a readable variable name versus the actual value of the String.

I'm reviewing some code like this in JavaScript and I'm inclined to recommend that the literals be replaced with a constant. However, I'm not sure the same reasons apply since there isn't a compiler and the cookie name is just as descriptive as a variable name would be.

Edit: Related to comments and responses received so far, I am definitely more concerned with the usage of constants versus how they are actually implemented. I see their value in Java and other compiled languages as a way to prevent errors, but I'm not sure I see the same value in Javascript.

As a documentation mechanism, say for magic numbers, I think having a named variable (even if it's not enforced as a constant) is still a good way to improve readability. But for string literals, I'm not sure this:

var trackingCookieName = "trackingCookie";

is any better than just using "trackingCookie" since you could typo either the literal or the variable name and either way, it would only be caught at runtime.

Upvotes: 7

Views: 9858

Answers (7)

cbmeeks
cbmeeks

Reputation: 11420

In the debate of constants in JavaScript, I personally prefer the following method (which is closer to enums, really).

var DIR = {
    North: [-1, 0],
    NorthEast: [-1, 1],
    East: [0, 1],
    SouthEast: [1, 1],
    South: [1, 0],
    SouthWest: [1, -1],
    West: [0, -1],
    NorthWest: [-1, -1]
};

Which makes it easy to use it like:

var myDirection = DIR.SouthEast;

Plus, modern IDE's can provide Intellisense for the values which really helps.

The other method mentioned by @Travis-J is nice and a lot of frameworks use it (Sencha, etc.). But for something that is close to a constant or enum in JS, I prefer my above method.

But you could certainly do it like Travis mentioned:

var Directions = (function() {
    var consts = {
        'North': [-1, 0],
        'NorthEast': [-1, 1],
        'East': [0, 1],
        'SouthEast': [1, 1],
        'South': [1, 0],
        'SouthWest': [1, -1],
        'West': [0, -1],
        'NorthWest': [-1, -1]
    };

    return {
        get: function(name) {
            return consts[name];
        }
    }
})();

But the problem I have with that is now you have to know the proper keys.

var myDirection = Directions.get('SouthEast');
var myDirection = Directions.get('SOUTHEAST');  //  null

Hope that provides a little help.

Upvotes: 1

sam
sam

Reputation: 40698

Extracting string literals to constants means

  • Tools like JSHint can identify misspelled variable names
  • Compressors can abbreviate variable names for smaller output
  • You change string values in exactly 1 place

Upvotes: 11

AdvilUser
AdvilUser

Reputation: 3452

OK, I agree that this might be subjective choice. Here are the reasons why I am biased towards using something equivalent to constants in JavaScript. First, here is how I might define my constants (or these are more like ENUMs):

function ENUM(name) {
  window[name] = name; // depending on platform I am on
}

Then, in global scope, probably in some file, I do

ENUM("MSG_DOOR_OPEN");
ENUM("MSG_DOOR_CLOSED");

And, I use this in my code like:

obj.notify(MSG_DOOR_OPEN);

The reason I like this better are:

  1. If I misspell something, I get some undefined reference error, which makes it very easy to spot in any JavaScript console.
  2. This way, I am referring to a pre-allocated string object, rather than creating new string object.
  3. I don't have to quote the thing -- looks nicer, especially in vim.

Downside:

  1. Yes, this is a global variable.
  2. Not name-spaced (other that MSG_ prefix).
  3. It's a hassle if you want to do this for everything. (you don't have to)

But for important things like message names, etc., I like doing it like this. Besides, having all message names defined in 1 place is good anyways. I am not a JavaScript expert or anything, so please correct me if I am wrong...

Upvotes: 1

JeanK
JeanK

Reputation: 1775

I agree with gdoron when he says that it is subjective, indeed, what we call conventions for programming languages, is actually an agreement among developers in how in their perspective the code would be clearer, easier to give maintenance and etc.

I brought the "convention" thing, because this "const" thing is pretty much about it, and there are some people/organizations that use these languages a lot and define some good practices for them. You can use these conventions in the way that suits you better, because they are slightly different between them, so you can adapt as you get experience. Here they are:

Google Style Guide

JS Crockford Style Guide

Upvotes: 1

Travis J
Travis J

Reputation: 82297

Javascript const isn't widely supported so I would say No, its not best practice.

"The current implementation of const is a Mozilla-specific extension and is not part of ECMAScript 5. It is supported in Firefox & Chrome (V8) and partially supported in Opera 9+ and Safari. It is not supported in Internet Explorer 6-9, or in the preview of Internet Explorer 10. The const keyword currently declares the constant in the function scope (like variables declared with var).

const is going to be defined by ECMAScript 6, but with different semantics. Similar to variables declared with the let statement, constants declared with const will be block-scoped." - https://developer.mozilla.org/en/JavaScript/Reference/Statements/const

Moreover, if you would like to implement a true const in javascript then wrap it in an object and only provide the get functionality.

Something like this:

var Cookies = (function()
{
 var consts = 
 {
  'APPLICATION': '21930857a3e',
  'SERVER': '435a3456jh5'
 };
 return
 {
  get: function(name)
  { 
   return consts [name];
  }
 };
}
)();

And then retrieve them:

document.write('<img src="' + Cookies.get('APPLICATION') + '" />')

or however you wish to use the constants.

Upvotes: 1

Jeffrey Sweeney
Jeffrey Sweeney

Reputation: 6124

Using constants is always better, regardless of the language (ok, maybe you can find a good exception). The only time I use string literals is if I'm making a file parsers or if I'm short on time and don't want to make a list of constants.

Of course, too many constants can be harder to read... It really depends on how obscure the string literals are.

Regardless, Javascript is a string-heavy language (as any interpreted language would be). You can extract fields from objects based off the string name of the object (container["innerObject"]), and it's almost too easy to run code through a string.

Upvotes: 0

gdoron
gdoron

Reputation: 150293

The answer is subjective. as you wrote, there is no compiler or constants.

So if it helps you reading and maintaining the code if the strings are stored in variables, do it, otherwise avoid it...

Upvotes: 6

Related Questions