JSHint's inspections now built into PhpStorm informed me about JavaScript magic numbers and I realise it'll make for clearer code to avoid using them.
I tried this:
var constants = {
millisecs: 1000,
secs: 60
};
and also this:
var constants = function () {
this.millisecs = 1000;
this.getMillisecs = function () {
return this.millisecs;
};
};
JsHint complains about both.
Taking the solution from this answer though works fine:
var constants = (function() {
var millisecs = 1000,
defaultMsgsPerSecond = 60;
this.getMillisecs = function() { return millisecs; };
this.getDefaultMsgsPerSecond = function() { return defaultMsgsPerSecond; };
})();
Presumably because of the closure. Why is it that this is accepted, whereas the other two suggestions taken from another SO question are not?
Edit: Although not triggering an error, it doesn't actually work. It errors to say constants is undefined. JsFiddle.
To clarify - by "works" I mean "doesn't trigger a warning from JsHint"
What Are Magic Numbers? Magic numbers are unique values, typically numerical, with unexplained meaning in your program that could be replaced by a named constant. Date.
A number is said to be a magic number, if the sum of its digits are calculated till a single digit recursively by adding the sum of the digits after every addition. If the single digit comes out to be 1,then the number is a magic number.
magic number, in physics, in the shell models of both atomic and nuclear structure, any of a series of numbers that connote stable structure. The magic numbers for atoms are 2, 10, 18, 36, 54, and 86, corresponding to the total number of electrons in filled electron shells.
In EcmaScript 6, you'll be able to just do:
const MILLISECS = 1000;
const DEFAULT_MSG_PER_SECOND = 60;
But until then, you can use EcmaScript 5's Object.freeze:
var constants = {
millisecs: 1000,
defaultMsgPerSecond: 60
};
var constants = Object.freeze(constants);
// Now constants is in fact... a constant!
constants.millisecs = 999;
constants.millisecs; // Still === 1000
And if it's your nature to be verbose, you can try Object.defineProperties:
var constants = {};
Object.defineProperties(constants, {
'millisecs': {
value: 1000,
writable: false
},
'defaultMsgPerSecond': {
value: 60,
writable: false
},
});
// Again, constants is in fact... a constant!
constants.millisecs = 999;
constants.millisecs; // Still === 1000
about your edit
I think you wanted to new
the inline object:
var constants = new (function() {
var millisecs = 1000,
defaultMsgsPerSecond = 60;
this.getMillisecs = function() { return millisecs; };
this.getDefaultMsgsPerSecond = function() { return defaultMsgsPerSecond; };
})();
But JSHint will also complain about that: Weird construction. Is 'new' unnecessary?
.
If you use it as a closure, then you need to actually return something. If you don't, constants
will indeed contain undefined
. An easy fix would be to return this
, but that would be a bad solution because you're extending this
which is an instance of an object you do not own.
So returning an inline object seems to be the solution here:
var constants = (function() {
var millisecs = 1000,
defaultMsgsPerSecond = 60;
return {
getMillisecs: function() { return millisecs; }
getDefaultMsgsPerSecond: function() { return defaultMsgsPerSecond; }
};
})();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With