web-dev-qa-db-fra.com

Pourquoi var x = x = x || {} plus complet que var x = x || {}?

Dans mon effort pour écrire du code Javascript propre en tant que débutant, je lisais récemment cet article à propos de l'espacement des noms en JavaScript lorsque je suis tombé sur ce paragraphe:

Le code tout en haut de l'exemple suivant illustre les différentes manières de vérifier si une variable (espace de nom d'objet) existe déjà avant de la définir. Les développeurs utilisent généralement l'option 1, mais les options 3 et 5 peuvent être considérées comme plus complètes et l'option 4 est considérée comme une bonne pratique.

// This doesn't check for existence of 'myApplication' in
// the global namespace. Bad practice as you can easily
// clobber an existing variable/namespace with the same name
var myApplication = {};

/*
The following options *do* check for variable/namespace existence.
If already defined, we use that instance, otherwise we assign a new
object literal to myApplication.

Option 1: var myApplication = myApplication || {};
Option 2  if(!MyApplication) MyApplication = {};
Option 3: var myApplication = myApplication = myApplication || {}
Option 4: myApplication || (myApplication = {});
Option 5: var myApplication = myApplication === undefined ? {} : myApplication;

*/

L'option 1 est certainement celle que j'ai vue utiliser la plupart du temps, et je la comprends bien.

L'option 2 est correcte, mais il semble manquer d'un var myApplication Auparavant ou d'un if(!window.myApplication) sinon, si myApplication n'est pas dans la portée globale la condition if(!myApplication) émettrait une erreur, n'est-ce pas?

L'option 3 est celle qui me pose problème: ma compréhension est que le myApplication = myApplication Est exécuté en premier, avec myApplication dans la portée globale (en raison de var au début). Mon problème est que je ne peux pas penser à un cas où cette option fait autre chose que l'option 1.

Option 4 à mes yeux aurait été mieux écrit window.myApplication || (myApplication = {}) pour éviter de générer une erreur si myApplication n'est pas dans la portée globale.

L'option 5 exclut les valeurs de false-y autres que undefined mais est-ce une bonne idée? Si myApplication est une chaîne vide, le reste du code échouera probablement, n'est-ce pas?

Quelqu'un pourrait-il nous éclairer sur les différences entre les différentes options et expliquer en particulier pourquoi l'option 3 est décrite comme étant plus complète?

35
Jacques Gaudin

Si l'article affirme que l'option 3 est "plus approfondie", elle est incorrecte. Il n'y a aucun point au milieu de cette chaîne d'affectation du tout.

Quelqu'un pourrait-il nous éclairer sur les différences entre les différentes options et expliquer en particulier pourquoi l'option 3 est décrite comme étant plus complète?

Tout d'abord, une mise en garde: ici en 2018, vous ne voudrez probablement pas utiliser l'une de ces méthodes. Au lieu de cela, utilisez les modules appropriés, via l'une des différentes syntaxes de définition de module ( AMD , CommonJS , RequireJS ) avec un outil pertinent ou via les modules ES2015 + avec import et export (et probablement un outil pertinent tel que - Babel et peut-être Webpack ou Browserify , bien que les versions actuelles de Chrome, Safari et Edge prennent en charge les modules de manière native et que Firefox le soit également derrière un drapeau) .

Pourquoi var x = x = x || {} Est-il plus complet que var x = x || {}?

Ce n'est pas.

L'option 2 est correcte, mais il semble manquer d'un var myApplication Auparavant ou d'un if(!window.myApplication) sinon, si myApplication n'est pas dans la portée globale la condition if(!myApplication) émettrait une erreur, n'est-ce pas?

Oui. (En supposant que la production se produise au niveau global. Si ce n’est pas le cas et qu’il existe un myApplication dans le contenu dans la chaîne d’étendue actuelle, il ne sera pas lancé car myApplication ne le sera pas. être un symbole non résolu.)

L'option 3 est celle qui me pose problème: ma compréhension est que le myApplication = myApplication Est exécuté en premier, avec myApplication dans la portée globale (en raison de var au début). Mon problème est que je ne peux pas penser à un cas où cette option fait autre chose que l'option 1.

Non, si vous avez

var myApplication = myApplication = myApplication || {}

c'est l'ordre dans lequel les choses se passent:

  1. var myApplication Crée le global s'il n'existe pas déjà, le laisse intact s'il le fait
  2. myApplication || {} Est évalué et prend soit la valeur dans myApplication (si c'est la vérité) ou {} (Sinon); appelons cela value1
  3. myApplication = value1 (Celui du milieu) est exécuté et le résultat est value1
  4. myApplication = value1 (Celui de gauche) est à nouveau exécuté sans raison valable

Option 4 à mes yeux aurait été mieux écrit window.myApplication || (myApplication = {}) pour éviter de générer une erreur si myApplication n'est pas dans la portée globale.

Effectivement.

L'option 5 exclut les valeurs de false-y autres que undefined mais est-ce une bonne idée? Si myApplication est une chaîne vide, le reste du code échouera probablement, n'est-ce pas?

Oui.

54
T.J. Crowder