【问题标题】:Avoiding using magic numbers in JavaScript - alternatives that work with JsHint避免在 JavaScript 中使用幻数 - 与 JsHint 一起使用的替代方案
【发布时间】:2012-08-16 14:07:54
【问题描述】:

现在 PhpStorm 中内置的 JSHint 的检查功能让我了解了 JavaScript 幻数,我意识到这将使代码更清晰,从而避免使用它们。

我试过了:

var constants = {
    millisecs: 1000,
    secs: 60
};

还有这个:

var constants = function () {
    this.millisecs = 1000;
    this.getMillisecs = function () {
        return this.millisecs;
    };
};

JsHint 抱怨两者。

this answer 获取解决方案虽然效果很好:

var constants = (function() {
    var millisecs = 1000,
        defaultMsgsPerSecond = 60;
    this.getMillisecs = function() { return millisecs; };
    this.getDefaultMsgsPerSecond = function() { return defaultMsgsPerSecond; };
})();

大概是因为关闭了。为什么这被接受了,而从另一个 SO 问题中提取的其他两个建议却没有?

编辑:虽然没有触发错误,但它实际上不起作用。说常量未定义是错误的。 JsFiddle.

澄清一下——“有效”是指“不会触发来自 JsHint 的警告”

【问题讨论】:

  • 前两个代码示例中明显出现的一个问题,但在后一个代码示例中缺少的是,“常量”不是那么恒定 - 也就是说,可以稍后在代码中更改(使用constants.millisecs = 100;).
  • @penartur 让我印象深刻 - 工作示例立即调用自身,使其属性私有,因此只有两个 getter 被暴露?

标签: javascript magic-numbers


【解决方案1】:

在 EcmaScript 6 中,您将能够:

const MILLISECS = 1000;
const DEFAULT_MSG_PER_SECOND = 60;

但在那之前,您可以使用 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

如果你的天性是冗长,你可以试试 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

【讨论】:

  • 所有 3 种方式都不错,但仅使用 const MILLISECS = 1000; 就简单明了。我倾向于使用第三种方法来创建我不希望任何人能够更改的用户对象之类的东西。
【解决方案2】:

关于您的修改

我想你想new 内联对象:

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

但是 JSHint 也会抱怨:Weird construction. Is 'new' unnecessary?

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

所以返回一个内联对象似乎是这里的解决方案:

var constants = (function() {
    var millisecs = 1000,
        defaultMsgsPerSecond = 60;
    return {
        getMillisecs: function() { return millisecs; }
        getDefaultMsgsPerSecond: function() { return defaultMsgsPerSecond; }
    };
})();

【讨论】:

    猜你喜欢
    • 2020-02-26
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 2013-11-18
    • 2011-06-16
    • 2013-11-06
    • 2015-07-06
    • 1970-01-01
    相关资源
    最近更新 更多