In JavaScript wird „with“ verwendet, um die Gültigkeitskette einer Anweisung zu erweitern. Es wird normalerweise als Abkürzung verwendet, um wiederholt auf mehrere Eigenschaften im selben Objekt zu verweisen, ohne wiederholt auf das Objekt selbst zu verweisen Stellungnahme...}".
Die Betriebsumgebung dieses Tutorials: Windows 7-System, JavaScript-Version 1.8.5, Dell G3-Computer.
Grundlegende Verwendung von Javascript mit
Die ursprüngliche Absicht der with-Anweisung besteht darin, eine Kurzschriftmethode im Namespace-Stil für den ebeneweisen Objektzugriff bereitzustellen. Das heißt, im angegebenen Codebereich befindet sich das Objekt direkt über den Knotennamen aufgerufen.
Die with-Anweisung wird verwendet, um die Gültigkeitskette einer Anweisung zu erweitern. Die Syntax lautet wie folgt:
with (expression) { statement }
Ausdruck
Fügt den angegebenen Ausdruck zur Bereichskette hinzu, die beim Auswerten von Anweisungen verwendet wird. Klammern um den Ausdruck sind erforderlich.
Aussage
Jede Aussage. Um mehrere Anweisungen auszuführen, verwenden Sie eine Blockanweisung ({ ... }), um die Anweisungen zu gruppieren.
with wird normalerweise als Abkürzung verwendet, um wiederholt auf mehrere Eigenschaften im selben Objekt zu verweisen, ohne wiederholt auf das Objekt selbst zu verweisen.
Zum Beispiel gibt es derzeit ein Objekt wie dieses:
var obj = { a: 1, b: 2, c: 3 };
Wenn Sie den Wert jedes Elements in obj ändern möchten, kann die allgemeine Schreibmethode wie folgt aussehen:
// 重复写了3次的“obj” obj.a = 2; obj.b = 3; obj.c = 4;
Mit der Schreibmethode gibt es eine einfache Abkürzungsmethode
with (obj) { a = 3; b = 4; c = 5; }
In diesem Code wird die with-Anweisung verwendet, um das obj-Objekt zu verknüpfen. Dies bedeutet, dass jede Variable innerhalb des with-Codeblocks zunächst als lokale Variable betrachtet wird, wenn die lokale Variable mit einem bestimmten Attribut verknüpft ist Das obj-Objekt Mit demselben Namen zeigt diese lokale Variable auf das obj-Objektattribut.
Nachteile von with
Im obigen Beispiel können wir sehen, dass with uns dabei helfen kann, den Code sehr gut zu vereinfachen. Aber warum wird es nicht empfohlen? Lassen Sie uns über die Mängel von with sprechen:
Führen zu Datenlecks
Schauen wir uns den folgenden Teil des Codes an
function foo(obj) { with (obj) { a = 2; } } var o1 = { a: 3 }; var o2 = { b: 3 } foo(o1); console.log(o1.a); //2 foo(o2); console.log(o2.a); //underfined console.log(a); //2,a被泄漏到全局作用域上
Analysieren wir zunächst den obigen Code. Im Beispiel werden zwei Objekte o1 und o2 erstellt. Einer von ihnen hat das Attribut a, der andere nicht. Die Funktion foo(obj)
akzeptiert einen formalen Parameter von obj, der eine Objektreferenz ist, und führt with(obj) {...}
für die Objektreferenz aus. Innerhalb des with-Blocks gibt es eine lexikalische Referenz auf a, die eigentlich eine LHS-Referenz ist, und ihr ist 2 zugewiesen. foo(obj)
函数接受一个 obj 的形参,该参数是一个对象引用,并对该对象引用执行了 with(obj) {...}
。在 with 块内部,对 a 有一个词法引用,实际上是一个 LHS引用,将 2 赋值给了它。
当我们将 o1 传递进去,a = 2
赋值操作找到了 o1.a 并将 2 赋值给它。而当 o2 传递进去,o2 并没有 a 的属性,因此不会创建这个属性,o2.a 保持 undefined。
但为什么对 o2的操作会导致数据的泄漏呢?
这里需要回到对 LHS查询
的机制问题。
当我们传递 o2 给 with 时,with 所声明的作用域是 o2, 从这个作用域开始对 a 进行 LHS查询
。o2 的作用域、foo(…) 的作用域和全局作用域中都没有找到标识符 a,因此在非严格模式下,会自动在全局作用域创建一个全局变量),在严格模式下,会抛出ReferenceError
a = 2
o1.a und weist ihm 2 zu. Wenn o2 übergeben wird, verfügt o2 über keine Eigenschaft, sodass diese Eigenschaft nicht erstellt wird und o2.a undefiniert bleibt. Hier müssen wir zum Mechanismus derAber warum kommt es durch den Betrieb von o2 zu Datenlecks?
LHS-Abfrage
zurückkehren. Wenn wir o2 an with übergeben, ist der von with deklarierte Bereich o2, und die LHS-Abfrage
für a beginnt in diesem Bereich. Der Bezeichner a wird nicht im Bereich von o2, im Bereich von foo(...) und im globalen Bereich gefunden, daher wird im nicht-strikten Modus
Im strengen Modus
wird eineReferenceError
-Ausnahme ausgelöst. Ein weiterer Grund, warum mit nicht empfohlen wird, ist. Im strengen Modus ist with vollständig verboten, ebenso wie die indirekte oder unsichere Verwendung von eval(…).
Leistungseinbußen
mit werden zur Laufzeit Bereiche geändert oder neue erstellt, wodurch andere lexikalische Bereiche, die zum Zeitpunkt des Schreibens definiert werden, ausgetrickst werden. Mit kann der Code skalierbarer gemacht werden. Obwohl oben die Möglichkeit eines Datenlecks besteht, kann dies mit ein wenig Aufmerksamkeit vermieden werden.
Die Antwort ist nein. Schauen wir uns den folgenden Teil des Codes aus den spezifischen Gründen an.
Der folgende Code kann kopiert und direkt ausgeführt werdenDer pessimistischste Fall ist, dass alle Optimierungen möglicherweise bedeutungslos sind, wenn mit angezeigt wird. Daher besteht der einfachste Ansatz der Engine darin, überhaupt keine Optimierung vorzunehmen. Wenn der Code häufig with oder eval() verwendet, wird er definitiv sehr langsam ausgeführt. Egal wie intelligent die Engine versucht, die Nebenwirkungen dieser pessimistischen Situationen zu minimieren, sie kann nicht vermeiden, dass der Code ohne diese Optimierungen langsamer läuft . 【Verwandte Empfehlungen: , Web-Frontend】 Das obige ist der detaillierte Inhalt vonSo verwenden Sie es in Javascript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!<script>
function func() {
console.time("func");
var obj = {
a: [1, 2, 3]
};
for(var i = 0; i < 100000; i++)
{
var v = obj.a[0];
}
console.timeEnd("func");
}
func();
function funcWith() {
console.time("funcWith");
var obj = {
a: [1, 2, 3]
};
with(obj) {
for(var i = 0; i < 100000; i++) {
var v = a[0];
}
}
console.timeEnd("funcWith");
}
funcWith();
</script>