En JavaScript, with est utilisé pour étendre la chaîne de portée d'une instruction. Il est généralement utilisé comme raccourci pour référencer à plusieurs reprises plusieurs propriétés dans le même objet sans référencer à plusieurs reprises l'objet lui-même ; déclaration...}".
L'environnement d'exploitation de ce tutoriel : système Windows 7, JavaScript version 1.8.5, ordinateur Dell G3.
Utilisation de base de javascript avec
L'intention initiale de l'instruction with est de fournir un raccourci de style espace de noms pour l'accès aux objets niveau par niveau, c'est-à-dire que dans la zone de code spécifiée, l'objet est appelé. directement via le nom du nœud.
L'instruction with est utilisée pour étendre la chaîne de portée d'une instruction. La syntaxe est la suivante :
with (expression) { statement }
expression
Ajoute l'expression donnée à la chaîne de portée utilisée lors de l'évaluation des instructions. Les parenthèses autour de l'expression sont obligatoires.
déclaration
Toute déclaration. Pour exécuter plusieurs instructions, utilisez une instruction de bloc ({ ... }) pour regrouper les instructions.
with est généralement utilisé comme raccourci pour référencer à plusieurs reprises plusieurs propriétés dans le même objet sans référencer à plusieurs reprises l'objet lui-même.
Par exemple, il existe actuellement un objet comme celui-ci :
var obj = { a: 1, b: 2, c: 3 };
Si vous souhaitez changer la valeur de chaque élément dans obj, la méthode d'écriture générale peut être comme ceci :
// 重复写了3次的“obj” obj.a = 2; obj.b = 3; obj.c = 4;
Et en utilisant la méthode d'écriture with with, là sera un simple raccourci Méthode
with (obj) { a = 3; b = 4; c = 5; }
Dans ce code, l'instruction with est utilisée pour associer l'objet obj. Cela signifie qu'à l'intérieur du bloc de code with, chaque variable est d'abord considérée comme une variable locale si la variable locale est liée à un. certain attribut de l'objet obj De même nom, cette variable locale pointera vers l'attribut de l'objet obj.
Inconvénients de with
Dans l'exemple ci-dessus, nous pouvons voir que with peut très bien nous aider à simplifier le code. Mais pourquoi n’est-ce pas recommandé ? Parlons des lacunes de with :
Conduit à une fuite de données
Regardons la partie suivante du code
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被泄漏到全局作用域上
Tout d'abord, analysons le code ci-dessus. Dans l'exemple, deux objets o1 et o2 sont créés. L’un d’eux possède l’attribut a, l’autre non. La fonction foo(obj)
accepte un paramètre formel de obj, qui est une référence d'objet, et exécute with(obj) {...}
sur la référence d'objet. À l’intérieur du bloc with, il y a une référence lexicale à a, qui est en fait une référence LHS, et 2 lui est attribué. 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
trouve o1.a et lui attribue 2. Lorsque o2 est transmis, o2 n'a pas de propriété, donc cette propriété ne sera pas créée et o2.a reste indéfini. Ici, nous devons revenir au mécanisme deMais pourquoi le fonctionnement d'o2 entraîne-t-il une fuite de données ?
Requête LHS
. Lorsque nous passons o2 à with, la portée déclarée par with est o2 et la requête LHS
pour a démarre à partir de cette portée. L'identifiant a n'est pas trouvé dans le scope de o2, le scope de foo(...) et le scope global, donc en mode non strict
en mode strict
, une exceptionReferenceError
sera levée. Une autre raison pour laquelle with n'est pas recommandé est. En mode strict, with est totalement interdit, tout comme les utilisations indirectes ou dangereuses de eval(…).
Dégradation des performances
with modifiera ou créera de nouvelles étendues au moment de l'exécution, trompant ainsi d'autres étendues lexicales définies au moment de l'écriture. with peut rendre le code plus évolutif. Bien qu'il existe une possibilité de fuite de données ci-dessus, cela peut être évité avec un peu d'attention.
La réponse est non. Examinons la partie suivante du code pour les raisons spécifiques.
Le code suivant peut être directement copié et exécutéLe cas le plus pessimiste est que si avec apparaît, toutes les optimisations pourraient n'avoir aucun sens. Par conséquent, l’approche la plus simple que le moteur adoptera est de ne faire aucune optimisation du tout. Si le code utilise beaucoup de with ou eval(), il s'exécutera certainement très lentement. Peu importe à quel point le moteur tente de minimiser les effets secondaires de ces situations pessimistes, il ne peut éviter le fait que sans ces optimisations, le code s'exécutera plus lentement . 【Recommandations associées : Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!<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>