避免在JavaScript中使用魔术数字 - 与JsHint一起使用的替代方案

bcm*_*cfc 7 javascript magic-numbers

现在内置于PhpStorm的JSHint检查告诉了我关于JavaScript魔术数字的信息,并且我意识到这将使更清晰的代码避免使用它们.

我试过这个:

var constants = {
    millisecs: 1000,
    secs: 60
};
Run Code Online (Sandbox Code Playgroud)

还有这个:

var constants = function () {
    this.millisecs = 1000;
    this.getMillisecs = function () {
        return this.millisecs;
    };
};
Run Code Online (Sandbox Code Playgroud)

JsHint抱怨两者.

这个答案中解决方案虽然运行正常:

var constants = (function() {
    var millisecs = 1000,
        defaultMsgsPerSecond = 60;
    this.getMillisecs = function() { return millisecs; };
    this.getDefaultMsgsPerSecond = function() { return defaultMsgsPerSecond; };
})();
Run Code Online (Sandbox Code Playgroud)

大概是因为关闭.为什么这是被接受的,而从另一个SO问题中提出的另外两个建议却不是?

编辑:虽然没有触发错误,但实际上并不起作用.如果说常量未定义则错误.JsFiddle.

澄清 - 通过"作品"我的意思是"不会触发JsHint的警告"

rod*_*ira 5

在EcmaScript 6中,您将能够执行以下操作:

const MILLISECS = 1000;
const DEFAULT_MSG_PER_SECOND = 60;
Run Code Online (Sandbox Code Playgroud)

但在那之前,您可以使用EcmaScript 5的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
Run Code Online (Sandbox Code Playgroud)

如果您很冗长,可以尝试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
Run Code Online (Sandbox Code Playgroud)


huy*_*itw 4

关于您的编辑

我想你想要new内联对象:

var constants = new (function() {
    var millisecs = 1000,
        defaultMsgsPerSecond = 60;
    this.getMillisecs = function() { return millisecs; };
    this.getDefaultMsgsPerSecond = function() { return defaultMsgsPerSecond; };
})();
Run Code Online (Sandbox Code Playgroud)

JSHint 也会抱怨这一点:Weird construction. Is 'new' unnecessary?.

如果你将它用作闭包,那么你需要实际返回一些东西。如果不这样做,constants确实会包含undefined. 一个简单的解决方法是 return this,但这将是一个糟糕的解决方案,因为您正在扩展thiswhich 是您不拥有的对象的实例。

因此,返回内联对象似乎是这里的解决方案:

var constants = (function() {
    var millisecs = 1000,
        defaultMsgsPerSecond = 60;
    return {
        getMillisecs: function() { return millisecs; }
        getDefaultMsgsPerSecond: function() { return defaultMsgsPerSecond; }
    };
})();
Run Code Online (Sandbox Code Playgroud)