2009-12-18 14 views
31

Mögliche Duplizieren:
Are there legitimate uses for JavaScript’s “with” statement?"mit" Stichwort in Javascript

ich, dass in JavaScript vor kurzem entdeckt, ein in etwa wie folgt tun:

with document{ 
    write('foo'); 
    body.scrollTop = x; 
} 

Die Kehrseite Dies bedeutet, dass jede Variable überprüft werden muss, um festzustellen, ob sie zum Dokumentobjekt gehört, wodurch ein erheblicher Overhead entsteht.

Alternativ könnte man so etwas tun:

var d = document; 
d.write('foo'); 
d.body.scrollTop = x; 

Gibt es Situationen, in denen die Verwendung des ‚mit‘ Schlüsselwort gerechtfertigt ist?

Antwort

12

Hier sind einige Blog-Beiträge zur Unterstützung der mit Stichwort. Aber lies bitte den YUI Blogeintrag, den azazul auch gepostet hat!

http://webreflection.blogspot.com/2009/12/with-worlds-most-misunderstood.html http://webreflection.blogspot.com/2009/12/with-some-good-example.html

+0

@Abel, du hast Recht, das beantwortet meine Frage genauso gut wie eine riesige Einschränkung dort zu haften. –

+3

@Annie: Ich denke, Sie sollten hier einige Zitate einfügen, anstatt einfach zwei verwandte Artikel zu verknüpfen. Was passiert, wenn sie später zu einem 404 (oder ähnlichen) HTTP-Code führen (z. B. weil diese Artikel verschoben/gelöscht wurden)? – Sk8erPeter

+1

** Die Verwendung von 'with' wird nicht empfohlen und ist im strikten ECMAScript5-Modus verboten. Die empfohlene Alternative besteht darin, das Objekt zuzuweisen, dessen Eigenschaften Sie auf eine temporäre Variable zugreifen möchten. ** Quelle: [Mozilla Developer Network] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with) – Pankaj

50

es einfach nicht verwenden: http://yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/

JavaScripts with Anweisung gedacht war eine Kurz zu schaffen für das Schreiben von wiederkehrenden Objekte zugreift. Also statt

ooo.eee.oo.ah_ah.ting.tang.walla.walla.bing = true; 
ooo.eee.oo.ah_ah.ting.tang.walla.walla.bang = true; 

des Schreibens können Sie schreiben

with (ooo.eee.oo.ah_ah.ting.tang.walla.walla) { 
    bing = true; 
    bang = true; 
} 

Das viel schöner aussieht. Außer eine Sache. Es gibt keine Möglichkeit, die Sie erkennen können, indem Sie auf den Code schauen, der bing und bang geändert wird. Wird ooo.eee.oo.ah_ah.ting.tang.walla.walla geändert werden? Oder werden die globalen Variablen bing und bang geplättert werden? Es ist unmöglich, sicher zu wissen ...

Wenn Sie ein Programm nicht lesen können und sicher sein können, dass Sie wissen, was es tun wird, können Sie nicht darauf vertrauen, dass es richtig funktioniert. Aus diesem Grunde soll die with Aussage vermieden werden ...

+2

Ich kann das nicht genug ausdrücken: jede "mit" -ähnliche Syntax, wie die für JavaScript und Delphi, wo Sie nicht explizit angeben, welche Bezeichner zum "scoped" Objekt gehören und welche nicht , sind ** böse **, benutze diese Syntax nicht in diesen Sprachen. Insbesondere zukünftige Änderungen können das Verhalten dieses Codes ohne Warnung ändern. Wenn das kein Bug ist, der nur darauf wartet, passiert zu sein, dann weiß ich nicht, was ist. –

+1

Zum Beispiel, Visual Basic.NET hat es richtig, http://msdn.microsoft.com/en-us/library/wc500chb(VS.80).aspx, wo sie Sie zwingen, alle Bezeichner, die zu dem Zielobjekt gehören mit einem Punkt. –

+0

Ja, VB (.NET und vorher) hat es richtig gemacht, aber sie haben es auch falsch verstanden: Wenn du Late-Binding verwendest, hast du immer noch das selbe Problem. Und die Leistung mit 'mit' ist langsamer als ohne (aus welchem ​​Grund auch immer). – Abel

5

würde ich benutze es in der Produktion Code vermeiden, weil es nicht eindeutig ist, aber es gibt eine alternative Lösung für die for-Schleife-Verschlusslösung von with mit dem imitieren let Bindung, hier ist eine Kopie meiner vorherigen Antwort:

eine Alternative zur Standard-Verschlusslösung Funktionen innerhalb von einer for-Schleife:

<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> 

Credit nlogax für eine Bereitstellung von Lösung, die so ziemlich abgezockt I: Javascript infamous Loop issue?

Hier ist die Standardlösung:

<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> 
+2

Bitte stellen Sie sicher, dass Sie angeben, welcher Teil "mehrdeutig" ist, da der JavaScript-Interpreter und/oder -Compiler nie darüber verwirrt ist, was für den zu verwenden ist Kennung. Es sind zukünftige Änderungen und/oder was ein Programmierer eine Kennung als das Problem interpretieren könnte. –

12

Trotz Beratung im Gegenteil fast überall, denke ich, dass es Anwendungen für „mit“. Zum Beispiel arbeite ich an einem Domänenmodell-Framework für Javascript, das den Unterstrich so verwendet, wie jQuery "$" verwendet. Das bedeutet, dass ich ohne "mit" viele Unterstriche in meinem Code verstreut habe, die es weniger lesbar machen. Hier ist eine zufällige Zeile aus einer Anwendung mit dem Rahmen:

_.People().sort(_.score(_.isa(_.Parent)),'Surname','Forename'); 

während mit „mit“ es wie

with (_) { 
    ... 

    People().sort(score(isa(Parent)),'Surname','Forename'); 

    ... 
} 

Was wirklich nützlich wäre aussehen würde, ist eine schreibgeschützte Version von „mit“.

+0

Nicht immer SLOWER Laufzeit geben Sie Nebenwirkungen. Es ist vernachlässigbar, wenn Sie es nicht tausend Mal laufen lassen. – kroe

+2

Heutzutage könnte man mit ES6-Objekt-Destrukturierung stattdessen const {People, score, isa, Parent} = _; 'verwenden und nicht alle Risiken von' with (_) 'eingehen. –