Heim  >  Artikel  >  Web-Frontend  >  Das with-Schlüsselwort in javascript_javascript-Tipps verstehen

Das with-Schlüsselwort in javascript_javascript-Tipps verstehen

WBOY
WBOYOriginal
2016-05-16 15:15:291112Durchsuche

Apropos with-Schlüsselwort in js: Der erste Eindruck vieler Freunde könnte sein, dass die Funktion des with-Schlüsselworts darin besteht, den Umfang zu ändern, und der wichtigste Punkt ist, dass die Verwendung des with-Schlüsselworts nicht empfohlen wird. Nachdem wir gehört haben, dass das Schlüsselwort „with“ nicht empfohlen wird, ignorieren viele von uns das Schlüsselwort „with“ und denken, wir könnten es einfach ignorieren und einfach verwenden. Aber manchmal, wenn wir uns einige Code- oder Interviewfragen ansehen, gibt es Fragen im Zusammenhang mit dem Schlüsselwort „with“. Es gibt viele Fallstricke, denen Sie noch nie ausgesetzt waren, daher ist es immer noch notwendig, über das Schlüsselwort „with“ zu sprechen.

1. Grundlegende Anweisungen

Das Schlüsselwort with wird in der erweiterten js-Programmierung wie folgt beschrieben: Die Funktion der with-Anweisung besteht darin, den Bereich des Codes auf einen bestimmten Bereich festzulegen. Die grundlegende Syntax lautet wie folgt:

with (expression) statement;

Der Zweck der Verwendung des Schlüsselworts with besteht darin, die Arbeit des mehrmaligen Schreibens und Zugreifens auf dasselbe Objekt zu vereinfachen, wie im folgenden Beispiel:

var qs = location.search.substring(1);
var hostName = location.hostname;
var url = location.href;

Diese Codezeilen greifen auf die Eigenschaften im Standortobjekt zu. Wenn Sie das Schlüsselwort with verwenden, kann der Code wie folgt vereinfacht werden:

with (location){
  var qs = search.substring(1);
  var hostName = hostname;
  var url = href;
}

In diesem Code wird die with-Anweisung verwendet, um das Standortobjekt zuzuordnen. Dies bedeutet, dass jede Variable innerhalb des with-Codeblocks zunächst als lokale Variable betrachtet wird, wenn die lokale Variable denselben Namen wie eine Eigenschaft des Standorts hat Objekt, dann zeigt diese lokale Variable auf die Eigenschaft des Standortobjekts.
Hinweis: Die with-Anweisung kann nicht im strikten Modus verwendet werden.

2. Nachteile des with-Schlüsselworts

In der vorherigen Grundbeschreibung können wir sehen, dass eine der Funktionen von with darin besteht, den Code zu vereinfachen. Aber warum wird es nicht empfohlen? Lassen Sie uns über die Mängel von with sprechen:

1. Leistungsprobleme
2. Unklare Semantik und schwer zu debuggen

3. Leistungsprobleme

Lassen Sie uns zunächst über Leistungsprobleme bei der Verwendung des Schlüsselworts with sprechen. Schauen wir uns zunächst zwei Codeteile an:

Der erste Teil des Codes verwendet nicht das with-Schlüsselwort:

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");//0.847ms
}
func();

Der zweite Codeabschnitt verwendet das with-Schlüsselwort:

function funcWith() {
  console.time("funcWith");
  var obj = {
    a: [1, 2, 3]
  };
  var obj2 = { x: 2 };
  with (obj2) {
    console.log(x);
    for (var i = 0; i < 100000; i++) {
      var v = obj.a[0];
    }
  }
  console.timeEnd("funcWith");//84.808ms
}
funcWith();

Nach der Verwendung des Schlüsselworts with wird die Leistung des Codes stark reduziert. Die with-Anweisung im zweiten Codeabschnitt wirkt auf das obj2-Objekt, und dann wird im with-Block auf das obj-Objekt zugegriffen. Es gibt eine Ansicht, dass nach Verwendung des Schlüsselworts „with“ beim Zugriff auf eine Variable im „with“-Block zunächst gesucht wird, ob ein Attribut mit dem Namen obj in obj2 vorhanden ist. Wenn nicht, wird mit der nächsten Suche fortgefahren in der Leistung. Aber ist das wirklich der Grund, warum die Programmleistung tatsächlich nachlässt?
Ändern wir den zweiten Codeabschnitt wie folgt:

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");//88.260ms
}
funcWith();

Dieser Code wendet die with-Anweisung auf das obj-Objekt an und verwendet dann a, um auf das a-Attribut von obj zuzugreifen. Gemäß dem zuvor erwähnten Standpunkt kann das Attribut beim Zugriff auf das a-Attribut auf obj in gefunden werden Aber warum ist die Codeleistung immer noch reduziert?
Der wahre Grund ist: Nach der Verwendung des Schlüsselworts with kann die JS-Engine diesen Code nicht optimieren.
Die JS-Engine hat eine Kompilierungsphase, bevor der Code ausgeführt wird. Wenn das Schlüsselwort with nicht verwendet wird, weiß die JS-Engine, dass a ein Attribut für obj ist, und kann den Code statisch analysieren, um die Analyse des Bezeichners zu verbessern und so zu optimieren Der Code. Daher wird die Effizienz der Codeausführung verbessert. Nach Verwendung des Schlüsselworts „with“ kann die js-Engine nicht erkennen, ob es sich bei der a-Variablen um eine lokale Variable oder ein Attribut von obj handelt. Daher gibt die js-Engine die Optimierung dieses Codes auf, nachdem sie auf das Schlüsselwort „with“ gestoßen ist, sodass die Ausführungseffizienz verringert ist . .
Eine weitere Auswirkung der Verwendung des Schlüsselworts with auf die Leistung ist das js-Komprimierungstool, das diesen Code nicht komprimieren kann, was ebenfalls einen Einfluss auf die Leistung hat.

4. Unklare Semantik und schwer zu debuggen

Wie bereits erwähnt, hat es neben Leistungsproblemen auch den Nachteil einer unklaren Semantik und Schwierigkeiten beim Debuggen, was die Lesbarkeit des Codes erschwert und potenzielle Fehler verursachen kann.

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 ); // undefined
console.log( a ); // 2

Dieser Code ist leicht zu verstehen. In der Funktion „foo“ wird das Schlüsselwort „with“ verwendet, um auf das übergebene Objekt „obj“ zuzugreifen und dann das Attribut „a“ zu ändern. Wenn das o1-Objekt übergeben wird, gibt es kein Problem, da das o1-Objekt ein Attribut a hat. Wenn das o2-Objekt übergeben wird und das a-Attribut geändert wird, wird das geänderte a-Attribut zu einer globalen Variablen, da das o2-Objekt nicht über das a-Attribut verfügt. Dadurch entstehen potenzielle Fehler.

5. Erweiterte Analyse

Nachdem ich schon so viel gesagt habe, glaube ich, dass jeder verstanden hat, warum die Verwendung des Schlüsselworts with nicht empfohlen wird und welche Probleme auftreten können. Werfen wir einen Blick auf einige komplexere Situationen und schauen uns den folgenden Code an:

var obj = {
  x: 10,
  foo: function () {
    with (this) {
      var x = 20;
      var y = 30;
      console.log(y);//30
    }
  }
};
obj.foo();
console.log(obj.x);//20
console.log(obj.y);//undefined

在这段代码中,分别输出30,20,undefined的。涉及的知识点也比较多:with关键字,this关键字,变量提升等等,我们来一一解释一下。
1、this关键字
关于this关键字的文章google上面相当多,这里不再赘述,我们只需记住一点:this关键字始终指向调用函数的对象。在这里,foo函数中,this指向的就是obj对象。因此在with(this)语句块里面,可以直接通过x变量来访问obj的x属性。
2、变量提升
js中的变量提升也是一个经常遇到的问题,我们可以简单理解成在js中,变量声明会被提升到函数的顶部,尽管有的时候,它是在后面声明的。

所以上面的代码可以解析为:

var obj = {
  x: 10,
  foo: function () {
    var x;//声明局部变量x
    var y;//声明局部变量y
    with (obj) {
      x = 20;//访问变量x,在obj上找到x,则修改为20
      y = 30;//访问变量y,在bojg上找不到y,则进一步查找,找到局部变量y,修改为30
      console.log(y);//30//直接输出局部变量y,
    }
  }
};
obj.foo();
console.log(obj.x);//20,obj.x已被修改为20
console.log(obj.y);//undefined,obj不存在y属性,则为undefined

上面的注释中,解释了代码的执行过程,相信大家已经理解了为什么会出处30,20,undefined的原因。

有兴趣的同学可以看看下面这段代码:

({
x: 10,
foo: function () {
  function bar() {
    console.log(x);
    console.log(y);
    console.log(this.x);
  }
  with (this) {
    var x = 20;
    var y = 30;
    bar.call(this);
  }
}
}).foo();

这段代码会输出什么?为什么呢?

总结

本文总结了with语句的特点和弊端,总的来说,强烈不推荐使用with关键字。其实在日常编码中,我们只需要知道不去使用with就可以了,但是有的时候我们可能会遇到一些关于with的奇奇怪怪的问题,想要找出真正的原因,就要深入理解with关键字,这有助于我们去深入学习JS这门语言,同时也是学习JS的一个乐趣。

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn