2012-08-21 20 views
7

Inspekcje JSHint wbudowane w PhpStorm poinformowały mnie o magicznych liczbach JavaScriptu i zdaję sobie sprawę, że dzięki temu jaśniejszy kod uniknie ich użycia.Unikanie używania magicznych liczb w JavaScript - alternatywy, które współpracują z JsHint

Próbowałem to:

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

i również w ten sposób:

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

JsHint narzeka obu.

Biorąc rozwiązanie z this answer ThoughtWorks porządku:

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

Przypuszczalnie z powodu zamknięcia. Dlaczego jest to akceptowane, podczas gdy pozostałe dwie sugestie zaczerpnięte z innego pytania SO nie są?

Edycja: Chociaż nie powoduje błędu, nie działa. Występuje błąd mówiący, że stałe są niezdefiniowane. JsFiddle.

Dla wyjaśnienia - przez "działa" znaczy "nie wywoła ostrzeżenie od JsHint"

+0

Jeden problem wyraźnie pojawiają się ze swoimi dwoma pierwszymi przykładami kodu, ale brakuje w tym ostatnim przykładzie kodu, jest to, że „stałe” nie są stałe - to jest, można później zmienić w kodzie (z 'stałych .millisecs = 100; '). – penartur

+0

@penartur, który wydaje mi się być odpowiedzią - działający przykład natychmiast wywołuje samą siebie, czyniąc jej właściwości prywatnymi, a zatem ujawniają się tylko dwa pozyskane? – bcmcfc

+0

@ Wouter-Huysentruit, czy mógłbyś wyjaśnić swoją edycję? – bcmcfc

Odpowiedz

3

o edycję

Chyba chciałeś new obiekt inline:

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

Ale JSHint również będzie narzekał na to: Weird construction. Is 'new' unnecessary?.

Jeśli używasz go jako zamknięcia, musisz zwrócić coś. Jeśli tego nie zrobisz, constants będzie zawierał undefined. Łatwą poprawką byłoby zwrócenie this, ale byłoby to złe rozwiązanie, ponieważ rozszerzasz this, która jest instancją obiektu, który nie jest Twoją własnością.

Więc wracając obiekt inline wydaje się być rozwiązaniem tutaj:

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

W ECMAScript 6, będziesz mógł po prostu zrobić:

const MILLISECS = 1000; 
const DEFAULT_MSG_PER_SECOND = 60; 

Ale do tego czasu, można użyć ECMAScript 5 za 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 

A jeśli to twoja natura być rozwlekły, można spróbować 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