2012-08-21 4 views
7

Les inspections de JSHint maintenant intégrées dans PhpStorm m'ont informé des nombres magiques JavaScript et je réalise que cela rendra le code plus clair pour éviter de les utiliser.Éviter d'utiliser des nombres magiques en JavaScript - des alternatives qui fonctionnent avec JsHint

J'ai essayé ceci:

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

et aussi ceci:

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

JsHint se plaint à la fois.

Prenant la solution de this answer Thoughtworks bien:

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

probablement en raison de la fermeture. Pourquoi est-ce que cela est accepté, alors que les deux autres suggestions tirées d'une autre question SO ne le sont pas? Edit: Bien que cela ne déclenche pas d'erreur, cela ne fonctionne pas réellement. Les erreurs pour dire les constantes sont indéfinies. JsFiddle.

Pour clarifier - par « fonctionne » je veux dire « ne déclenche pas un avertissement de JsHint »

+0

Un problème qui apparaît clairement avec vos deux premiers exemples de code, mais il manque dans ce dernier exemple de code, est que les « constantes » ne sont pas que constante - qui est, peuvent être modifiés ultérieurement dans le code (avec 'constantes .millisecs = 100; '). – penartur

+0

@penartur qui me semble être la réponse - l'exemple de travail s'appelle immédiatement, rendant ses propriétés privées et donc seuls les deux getters sont exposés? – bcmcfc

+0

@ Wouter-Huysentruit s'il vous plaît pourriez-vous expliquer votre montage? – bcmcfc

Répondre

3

votre modifier

Je pense que vous vouliez new l'objet en ligne:

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

Mais JSHint se plaindra aussi à ce sujet: Weird construction. Is 'new' unnecessary?.

Si vous l'utilisez comme une fermeture, vous devez retourner quelque chose. Si vous ne le faites pas, constants contiendra en effet undefined. Une solution facile serait de retourner this, mais ce serait une mauvaise solution car vous étendez this qui est une instance d'un objet que vous ne possédez pas.

donc retourner un objet en ligne semble être la solution ici:

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

En EcmaScript 6, vous serez en mesure de le faire:

const MILLISECS = 1000; 
const DEFAULT_MSG_PER_SECOND = 60; 

Mais jusque-là, vous pouvez utiliser Object.freeze de EcmaScript 5:

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 

Et si c'est votre nature d'être bavard, vous pouvez essayer 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 
Questions connexes