2012-08-21 1 views
7

Проверки JSHint, которые теперь встроены в PhpStorm, сообщили мне о магических числах JavaScript, и я понимаю, что это сделает более четкий код, чтобы избежать их использования.Избегание использования магических чисел в JavaScript - альтернативы, которые работают с JsHint

Я попытался это:

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»

+0

Одна из проблем, очевидно, появляются с первыми двумя примерами коды, но отсутствует в последнем примере коды, является то, что «константа» не то, что константа - то есть, может быть изменена позже в коде (с 'констант .millisecs = 100; '). – penartur

+0

@penartur, который поражает меня как ответ - рабочий пример сразу вызывает себя, делая его свойства закрытыми, и, таким образом, раскрываются только два геттера? – bcmcfc

+0

@ Wouter-Huysentruit, пожалуйста, вы можете объяснить свое редактирование? – bcmcfc

ответ

3

о правке

Я думаю, что вы хотели 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; } 
    }; 
})(); 
4

В 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 
Смежные вопросы