8

In static languages like Java/C#, I commonly make use of constants for strings or numbers, rather than insert them into the code alone. However, I tend to avoid this practice in JavaScript. More recently, as some other coders around me have taken this approach in JS, I decided I should probably solidify either my, or their, reasoning.

There is no actual "const" declaration syntax in JavaScript. We usually just settle for an informal policy of not changing uppercase properties. But my opinion is usually to avoid them altogether, because most of their benefits are lost in JavaScript. In Java, a misspelt string will cause the program to fail when you try to run it, at which point you correct it and move on. Having a static checker where both instances are pointing to the same constant eliminates that problem, as it can be found at compile-time. But JavaScript will simply have that problem all over the place, as you're ALWAYS going to discover your spelling's correctness at run-time:

Library = { doThing: function() }
setTimeout(function()
  Liberry.doThing()
  // No such object: Liberry
}, 0);

The best safeguard against this, usually, is "use strict". For developers that prefer it, I'm fine with them using that to find issues with undeclared variables more quickly. But my opinion has been that providing string constants for REST APIs, etc., doesn't actually safeguard you against anything. Another example:

CompanyAPI.constants.ENROLL_URL = "/rest/enroll";
CompanyAPI.constants.FIRST_NAME = "firstName";

ajax({url: CompanyAPI.constants.ENROLL_URL,
data: CompanyAPI.constants.FIRST_NAME
});
// vs.
ajax({url: "/rest/enroll",
data: "firstName"
});

...You meant to write the above, but then made typos. Whoops.

ajax({url: CompanyAPI.constants.ENROL_URL,
  data: CompanyAPI.constants.FIRS_NAME
});
// vs.
ajax({url: "/rest/enrol",
  data: "firsName"
});

The constant-based one will still provide undefined, while "firsName" is no better. To that end, I tend to just see this as a benefit of static languages, and not bother having a system to fix it (besides maybe starting to use "use strict" for debugging). Can some other people tell me what their preferred practice for string/integer constancy is?

EDIT: To clarify, my preference is usually to put strings like "firstName" directly inline with no top-level constant declaration - the penalties for misspelling it are the same either way. Strings that might get long, like a REST URL, I'll tend to define at the top of the file.

closed as primarily opinion-based by Eric King, Robert Harvey, david.pfx, Ampt, user40980 Jul 22 '14 at 15:56

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

  • FIRST_NAME? That looks like it comes from something server-side and is passed into the javascript. And that combined with you saying you come from Java/C#, I have the feeling you're misreading what these variables are for: Separating the data from the code, so that the .js file can be cached by the browser... – Izkata Jul 22 '14 at 0:43
  • @Izkata I'm not sure I get the comment about caching. This isn't server-generated JS (Although one possibility for these constants would be to have them come from the server - it would centralize things more, but I'd feel like that would be excessive complication and too many extra requests.) – Katana314 Jul 22 '14 at 13:31
  • It wouldn't generate any extra requests, the data would be set in the template and used in the javascript. It was the usage of FIRST_NAME in particular that had me wondering - does it not change per user? – Izkata Jul 22 '14 at 15:15
  • Yeah, that part was just laziness in writing the example; this instance is just sending the word "firstName" to the server which doesn't make much sense, but in general the idea would be to use that as a key for an input value. – Katana314 Jul 22 '14 at 15:24
5

Constants do serve a error-checking function in statically-typed languages, but they also serve a second purpose. They centralize information into one place. This is not lost when we move to JavaScript.

Imagine that your example looks more like this,

config.js:

CompanyAPI.constants.ENROLL_URL = "/rest/enroll";
CompanyAPI.constants.FIRST_NAME = "firstName";

enroll.js:

ajax({url: CompanyAPI.constants.ENROLL_URL,
    data: CompanyAPI.constants.FIRST_NAME
});

special-enroll.js:

ajax({url: CompanyAPI.constants.ENROLL_URL,
    data: CompanyAPI.constants.FIRST_NAME
});

need-to-enroll-from-this-other-place.js:

ajax({url: CompanyAPI.constants.ENROLL_URL,
    data: CompanyAPI.constants.FIRST_NAME
});

goto-enroll.js:

redirect({url: CompanyAPI.constants.ENROLL_URL,
    data: CompanyAPI.constants.FIRST_NAME
});

Notice how, now, these constants are showing up in files all over the place. If I wasn't using constants, I would have to find all the instances of that particular string, and replace them manually. Admittedly, there is duplication here, but notice that the last one is actually different. This means that even if we removed the duplication, we couldn't actually abstract this away. Now, because we are using constants, and CompanyAPI.constants.FIRST_NAME needs to change, we can change it in one and only one place, and it automatically changes everywhere.

If I'm using a string in only one place, and it is not configuration (ie, an array string index is not configuration), then I'll put it inline. If I find I'm using it in a few places close to each other, I'll look to refactor it into one use. If I cannot refactor, I would likely move it into a "class"-level constant.

  • 1
    There's a dark side to that too. Each time a piece of data is added/removed for one request, it must be added/removed to two different files. Plus, if the name of a piece of data changes, you could just change the constant - but then the code is harder to read, because it's one constant name referring to another variable name. (For instance, our company renamed something called "Enrollment codes" not once but twice.) JS's lack of automated Refactor tools means a lot of this centralization is lost. – Katana314 Jul 21 '14 at 19:43
3

Just like learning another language, one shouldn't compare it to his/her mother tongue. Some Languages often have concepts that are not found in others. We simply learn to accept them.

Constants in Java, C# and C++ do not exist in binary code. These constants were invented to help programmers and compilers. As this answer (https://stackoverflow.com/questions/130396/are-there-constants-in-javascript) says "Nothing's ever constant"

Therefore, the answer to your questions is in the Naming Convention and Code Review. You and your team will need to define how to name constants, agree that constants will not be modified, and use the code review as a way to enforce the rule. At the end of the day, it does not matter which way you decide to go, it will not be fool-proof.

My Preferred way of dealing with constants is

var NAMESPACE.CONSTANT = 1;

Not the answer you're looking for? Browse other questions tagged or ask your own question.