Question

Je trouve toujours le mot-clé with un peu ... énigmatique .

En bref, with se comporte comme ceci:

with (obj) {
    // do stuff
}

Cela ajoute obj à la tête de la chaîne de portée et exécute ensuite le avec bloc. Lorsque le bloc est terminé, il supprime obj de la tête de la chaîne de portée.

Selon MDC , cela vous permet de faire des choses comme

var a, x;
var r = 10;
with(Math) {
    a = PI * r * r;
    x = r * cos(PI / 2);
}

Je peux donc faire référence à des propriétés de Math - comme PI - directement, sans dire Math.PI. Ce qui est bien, mais un peu inutile.

Quelqu'un peut-il donner un exemple d'une utilisation intéressante de with?

Était-ce utile?

La solution

Une alternative à la solution de fermeture standard à l'aide des fonctions à l'intérieur d'une boucle for:

<a  href="#">blah</a><br>
<a  href="#">blah</a><br>
<a  href="#">foo</a><br>
<script>
    (function() {
    var anchors = document.getElementsByTagName('a');
        for ( var i = anchors.length; i--; ) {
            var link = anchors[i];
            with ({ number: i }) {
                link.onclick = function() {
                    alert(number);
                };
            }
        }
    })();
</script>

Crédit nlogax pour fournir une solution que je à peu près arnaquer: Javascript infâme problème Loop

Voici la solution standard:

<script>
    (function() {
    var anchors = document.getElementsByTagName('a');
    for ( var i = anchors.length; i--; ) {
        var link = anchors[i];
        (function(i) {
            link.onclick = function() {
                alert(i)
            }
        })(i);
    }
    })();
</script>

Autres conseils

Il faut dire ici que la déclaration de with en JavaScript est largement désapprouvée.

Voir de Douglas Crockford Avec Déclaration Considered Harmful .

Je ne peux pas le dire mieux que lui (sérieusement, cliquez sur le lien), mais en bref si vous faites ceci:

with (mySuperLongObjectReferenceThatIHateTyping) {
  propertyAlpha = 'a';
  propertyBeta = 2;
  propertyGamma = false;
}

Vous ne pouvez pas savoir en regardant ce code si vous attribuer des valeurs aux propriétés de l'objet mySuperLongObjectReferenceThatIHateTyping ou de l'objet global (fenêtre).

Crockford recommande ceci:

var o = mySuperLongObjectReferenceThatIHateTyping;
o.propertyAlpha = 'a';
o.propertyBeta = 2;
o.propertyGamma = false;

Ce qui est sans ambiguïté. Ou vous pouvez même utiliser une fonction de sorte que vous avez portée et de ne pas créer une autre variable globale:

(function(o) {
  o.propertyAlpha = 'a';
  o.propertyBeta = 2;
  o.propertyGamma = false;
})(mySuperLongObjectReferenceThatIHateTyping);

javascript John Resig microtemplating montre une utilisation intéressante pour avec.

Je l'utilise régulièrement pour ajouter plusieurs propriétés CSS à un objet style, par exemple

with(document.body.style) {
    color = 'green';
    background = 'red';
}

En outre, je l'ai utilisé au moins une fois pour affecter les propriétés d'un objet à des variables locales sans avoir à mémoriser une référence à l'objet lui-même.

Il est également une alternative à la fermeture lorsque vous voulez prendre un « instantané » de la valeur d'une variable:

var foo = [];
for(var i = 10; i--;)
    with({ i : i }) foo[i] = function() { document.writeln(i); };

// prints 0..9
for(var i = 0; i < foo.length; ++i)
    foo[i]();

Gardez à l'esprit que with peut avoir un impact sérieux performances que la chaîne de prototype de l'objet que vous avez ajouté à l'environnement lexical doit vérifier d'abord lors de la résolution un nom de variable.

La JS avec déclaration est comme la déclaration avec VB.net dire. Il est tout simplement un moyen d'éviter la répétition des propriétés / méthodes d'un objet.

Par exemple, on suppose un contrôle de l'étiquette est modifiée en fonction d'un événement / action. Cette contrôle d'étiquette possède des propriétés telles que FontColor, CssClass, la visibilité, etc.

Au lieu de l'écriture programmeur:

myLabel.FontColor=Color.Blue
myLabel.CSSClass="SomeCSSClass"
myLabel.Visiblity=True
myLabel.Text = "Hello World"

On peut réduire cela à:

With myLabel
  .Text = "Hello World"
  .FontColor = Color.Blue
  .CssClass="SomeCSSClass"
  .Visibility=True
End With

Je ne suis pas connu en Javascript, juste commencer à comprendre comment penser qu'il devrait être utilisé, donc mon avis ne devrait pas porter le même poids que celui de quelqu'un qui est expérimenté dans la langue spécifique. Je serais intéressé par les réponses à mon idée.

Je suis expérimenté avec un style de définir des objets de classe comme ça dépend du Javascript avec déclaration. Je soumets que cela est une utilisation légitime.

Chaque objet de classe comme dans cette fonction de style comme une usine pour des objets pour satisfaire à quelque chose.

Ce style ne fait pas usage de ce mot-clé dans les méthodes d'instance.

Ce style que chaque objet conçoit généré sur l'un de ces objets de classe semblable est d'avoir un aspect public et un aspect privé. Un objet Javascript représente chacun de ces aspects. Les porteurs de références à l'objet se réfèrent en fait que l'aspect public. Les méthodes, cependant, connaissent les deux aspects et je mettre en œuvre ce avec des fermetures.

Je ne prétends pas que ce style est applicable aux cas où nous prêtons beaucoup sur le temps d'exécution ou mémoire. Je sacrifie délibérément un peu de chacun de ceux à l'efficacité de la programmation. Je pense trouver beaucoup de cas où je veux programmer quelque chose rapidement et avec peu de chance d'erreur, et où les exigences à l'exécution ne sera pas critique.

Depuis que j'essaie de code dans un navigateur plutôt que Node.js, une considération pratique de l'environnement de développement pour moi est que les erreurs de syntaxe dans un grand fichier source peut être difficile à cerner et corriger. Je contre ce problème en ajoutant du code par petits incréments. Par conséquent, je veux que les objets de la classe comme pour être en mesure d'accepter une définition instance de méthode à la fois, plutôt que d'exiger que toutes les définitions de méthode apparaissent dans un seul fichier source.

Je déclare un objet de classe comme initialement sans méthodes d'instance qui y sont définies, et je place l'objet de classe comme dans tout l'espace de noms que je suis la programmation dans.

Alors je l'appelle l'objet de classe semblable à plusieurs reprises à une méthode qu'il a appelé « init » et chaque fois, je passe un initialiseur , une fonction appelée lors de l'initialisation d'une instance.

Finalement, quand je commence à utiliser l'objet de classe comme en usine pour ses instances, chaque fois que je demande pour une nouvelle instance, il crée les aspects publics et privés de l'instance, relie l'aspect privé à celui du public, puis appelle tous les initialiseurs qui ont été définis, qui les traverse l'aspect privé de la nouvelle instance.

Dans mon style, chaque attribut public est une méthode. Toutes les variables dont les valeurs ne seront pas les fonctions doivent vivre du côté privé.

Une chose un initialiseur peut faire est d'établir une variable du côté privé.

Une autre chose un initialiseur peut faire est d'ajouter une méthode soit sur le public ou du côté privé.

questions d'ordre pour l'exécution des initialiseurs - l'objet de classe semblable est nécessaire pour les exécuter dans le même ordre dans lequel elles sont définies. Par conséquent, chaque initialiseur peut compter sur les aspects publics et privés de l'instance ayant les attributs qui ont été établies par les initialiseurs antérieures. Pour le programmeur, cela crée en effet une paire de lunettes lexicales, étant donné que les initialiseurs ne sont pas établis par le code conditionnel ou dynamique de toute nature; ils sont établis comme les fichiers source sont exécutées par le navigateur juste après qu'il lit et les parse.

Maintenant dans certaines langues, en particulier le langage Ruby et la langue auto, vous pouvez écrire un identifiant nu et avoir interprété comme un appel de méthode sur l'objet courant. Donc, en Ruby, « toto » peut signifier « self.foo » et Self, « toto » peut signifier « self foo » (la syntaxe d'appel de méthode diffère entre ces langues, mais au niveau de détail auquel je parle de la sémantique maintenant, « self.foo » en Ruby et « auto foo » dans self sont les mêmes). cette abbreviation sur l'existence de « soi » est particulièrement pratique pour appeler des méthodes privées et variables d'instance. La langue Javascript ne fournit pas cette commodité.

Dans des contextes à l'intérieur d'une méthode d'instance où je veux utiliser un attribut du côté privé ou public pour sa valeur (note, pas sur le côté gauche d'une cession), j'aime la commodité de se référer à l'attribut par juste son nom et ne pas avoir à écrire « vars. » ou « soi ». à gauche de celui-ci pour localiser (je l'utilise « vars » pour l'aspect privé et « auto » pour l'aspect public). Pour cette raison, j'Envelopper chaque initialiseur dans un Javascript avec déclaration. Cela me semble légitime, parce que dans mon style, la population de l'objet ciblé est établi lexicalement. Pour voir les attributs, le programmeur n'a besoin que de regarder les initialiseurs fournies plus haut dans les fichiers source au même objet comme la classe (qui est lui-même identifié par son nom dans le code source, donc à des fins génie logiciel, nous pouvons considérer comme une entité lexical, même si aucune des parseurs Javascript détecter ce sujet).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top