Dans JS, vous pouvez renvoyer un booléen ayant des propriétés personnalisées. Par exemple. Lorsque Modernizr teste le support vidéo, il renvoie true
ou false
le booléen renvoyé (Bool est le premier objet de classe dans JS) possède des propriétés spécifiant les formats pris en charge. Au début, cela m’a un peu surpris, puis j’ai commencé à aimer cette idée et à me demander pourquoi elle semble être utilisée avec parcimonie.
Cela ressemble à une manière élégante de traiter tous les scénarios dans lesquels vous voulez savoir en gros si quelque chose est vrai ou faux, mais vous pouvez être intéressé par des informations supplémentaires que vous pouvez définir sans définir d'objet de retour personnalisé ni utiliser une fonction de rappel prête à accepter plus de paramètres. Ainsi, vous conservez une signature de fonction très universelle sans compromettre la capacité de restitution de données plus complexes.
Il y a 3 arguments contre cela que je peux imaginer:
- C'est un peu inhabituel / inattendu quand il est probablement préférable que toute interface soit claire et non délicate.
- C’est peut-être un argument de paille, mais comme il s’agit d’un cas un peu tranchant, je peux imaginer qu’il se retourne discrètement dans certains optimiseurs JS, uglifier, ordinateurs virtuels ou après une modification mineure des spécifications du langage, etc.
- Il y a une meilleure façon - concise, claire et commune - de faire exactement la même chose.
Ma question est donc la suivante: existe-t-il de bonnes raisons d’éviter d’utiliser des booléens avec des propriétés supplémentaires? Sont-ils un tour ou un régal?
Avertissement de rebond de parcelle.
Ci-dessus se trouve la question initiale en pleine gloire. Comme Matthew Crumley et senevoldsen l'ont tous deux souligné, il est basé sur une fausse prémisse (falsie?). Conformément à la tradition JS, ce que Modernizr fait est un tour de langue malpropre. Cela revient à dire que JS a un booléen primitif qui, s'il est défini sur false, restera faux même après avoir essayé d'ajouter des accessoires (qui échoue en silence) et un objet booléen pouvant avoir des accessoires personnalisés, mais être un objet est toujours une vérité. Modernizr renvoie soit un objet booléen faux, soit un objet booléen de vérité.
Ma question initiale supposait que l'astuce fonctionnait différemment et que les réponses les plus courantes traitaient donc de l'aspect (parfaitement valide) des normes de codage. Cependant, je trouve que les réponses à cette question sont très utiles (ainsi que les arguments ultimes contre l’utilisation de la méthode), aussi j’en accepte un. Merci à tous les participants!
null
si ils ne sont pas pris en charge et, le cas échéant, un tableau de formats. Une liste est considérée comme une vérité dans JS etnull
est une fausseté.Réponses:
Outre les principes de conception généraux, tels que la responsabilité unique et la moindre surprise, il existe une raison spécifique à JavaScript qui n'est pas une bonne idée: il existe une énorme différence entre un
boolean
etBoolean
JavaScript qui l'empêche de fonctionner dans le cas général.boolean
est un type primitif, pas un objet et ne peut pas avoir de propriétés personnalisées. Expressions commetrue.toString()
travail parce que dans les coulisses, il se transforme en(new Boolean(true)).toString()
.Boolean
(avec un majuscule B) est un objet, mais a très peu d'utilisations utiles, et son utilisation enboolean
est certainement pas l'un d'entre eux. La raison en est que chaque propriétéBoolean
est "true", quelle que soit sa valeur , car tous les objets sont convertistrue
en un contexte booléen. Par exemple, essayez ceci:Donc, en général, il n’ya aucun moyen d’ajouter des propriétés à un booléen en JavaScript qui le laisse quand même se comporter de manière logique. Modernizr peut s'en tirer parce que les seuls ajoutent des propriétés aux "vraies" valeurs, qui fonctionnent comme vous le souhaitez (c'est-à-dire qu'elles fonctionnent dans des instructions if). Si la vidéo n'est pas du tout prise en charge,
Modernizr.video
elle sera réelleboolean
(avec la valeurfalse
) et ne pourra pas avoir de propriétés ajoutées.la source
true
conditionnel. Pourquoi utiliser explicitement unBoolean
?false
la fois, il est strictement 'faux' et falsifié (===
et==
fonctionne comme) MAIS en effet, vous ne pouvez réellement pas ajouter d'accessoires à bool primitive. La distinction entre Bool et bool m'a foudroyé apparemment.TypeError
si vous essayez d'ajouter une propriété (voir jsbin.com/yovasafibo/edit?js,console ).Félicitations, vous avez découvert des objets. La raison pour ne pas le faire s'appelle le principe du moindre étonnement . Être surpris par un design n'est pas une bonne chose.
Il n'y a rien de mal à regrouper ces informations, mais pourquoi voudriez-vous les cacher dans un Bool? Mettez-le dans quelque chose que vous vous attendez à avoir avec toutes ces informations. Bool inclus.
la source
L'argument principal contre lequel je m'oppose est le principe de responsabilité unique , un booléen ne devrait dire que si quelque chose est
true
oufalse
non, pas pourquoi, comment ou quoi que ce soit d'autre. Je suis fermement convaincu et pratique que d’autres objets devraient être utilisés pour communiquer cette information ou toute autre information.la source
Boolean
malgré les manigances.Puisque toute la raison pour laquelle on l'appelle une valeur booléenne est le fait que ce soit vrai ou faux, je n'aime pas l'idée, car vous minimisez à peu près tout son objectif de wikipedia
(mon gras)
la source
Ce n’est pas parce que vous le pouvez que vous devriez, vous pouvez très bien attacher des propriétés à n’importe quel objet dans JS (Booléens inclus)
Comment est-ce une mauvaise chose?
D'une part, vous pouvez attacher plus de données non pertinentes à un booléen (selon votre exemple), ce qu'un autre développeur ne s'attendra pas à recevoir, car pourquoi devrait-il être là?! Les bool sont juste pour le vrai et le faux.
Un contre-point consiste à attacher des propriétés utiles pouvant vous aider à gérer la valeur booléenne ( c'est ce que fait Java ).
Par exemple, vous pouvez attacher une fonction qui convertit la valeur booléenne en une chaîne, un
dirty
indicateur devenu vrai si la valeur a été modifiée, des observateurs et des rappels d'événements pouvant se déclencher lorsque la valeur est modifiée, etc.Cela ressemble à quelque chose qui ne devrait pas être stocké dans un booléen, mais plutôt à l'aide d'un ensemble de booléens ou d'un ensemble de propriétés contenant des booléens. Je pense qu'une meilleure approche serait de renvoyer un objet avec tous les formats et détails de support.
la source
Vous ne pouvez pas créer de booléens avec des propriétés personnalisées en JavaScript. Les échecs suivants (au moins en FF):
Vous pouvez utiliser ou hériter de Boolean, mais comme le dit Matthew Crumley, cela donne des résultats différents.
Boolean
est de typeObject
. Lorsque JS a besoin de la valeur booléenne d'une expression, il convertit à l'aide de la fonction de spécificationToBoolean
, ce qui indique que, pourObject
s, le résultat est toujourstrue
. Ainsi, la valeur estnew Boolean(false)
évaluée àtrue
! Vous pouvez le vérifier dans cet exemple: https://jsfiddle.net/md7abx5z/3/ .La seule raison pour laquelle cela fonctionne pour Modernizr est fortuite. Ils créent uniquement un
Boolean
objet lorsque la condition est vraie. Quand ils évaluent faux, ils retournent simplement à l'ordinairefalse
. Donc, cela fonctionne car ils ne renvoient desBoolean
objets que lorsque le résultat est vrai, de toute façon, et jamais lorsqu'il est faux.la source
Je comprends que le contexte a changé, mais je voudrais répondre à la question initiale que j’avais lue en utilisant JS comme exemple, mais pas uniquement JS.
Ajouter des propriétés à un booléen ne poserait pas de problème SI les propriétés avaient quelque chose à voir avec true / false, pas avec la variable contenant la valeur. Par exemple, ajouter une méthode toYesNoString serait bien, ajouter un numberOfChildren à une valeur hasChildren ne le serait pas, pas plus que questionsMassed studentPassed. Il n'y a pas grand-chose que vous puissiez ajouter à un booléen, mis à part diverses représentations de chaîne, la seule propriété à laquelle cela puisse donner un sens est originalExpression. Mais y ajouter n'est pas nécessairement une mauvaise idée en théorie.
la source
Si je regarde le code, il ne s'agit pas vraiment de donner des propriétés booléennes personnalisées, mais d'une méthode ayant des méthodes de retour avec des signatures différentes.
Si elle est fausse, vous obtenez une primitive fausse et, si elle est vraie, elle retourne un objet qui, par définition, est interprété comme étant vrai en javascript.
Donc, à mon avis, votre question ne devrait pas être de savoir si c’est une bonne idée de donner des propriétés personnalisées à un booléen, mais bien d’avoir des méthodes avec plusieurs signatures de retour.
la source
Dans l'exemple donné, ne pouvez - vous pas simplement renvoyer un tableau de tous les formats vidéo pris en charge?
Je dirais au moins que l'utilisation de array est un peu moins surprenante que d'avoir des "booleans personnalisés".
En Javascript, un tableau vide est même considéré comme de la fausseté , alors qu'un tableau non vide est une vérité , alors avec un peu de chance, vous pouvez simplement passer à des tableaux et tout fonctionnerait comme avantEdit Nope, idiot moi de penser que je pourrais me souvenir de la vérité d'objets en JavaScript: Pla source
""
a typeof"string"
mais c'est en réalité de la fausseté[].length
falsey si longueur est0
, n’est pas beaucoup plus typé et, à mon avis, est une meilleure indication de l’intention que ne leif([])
serait même si cela fonctionnait.