Maison > interface Web > Questions et réponses frontales > Comment utiliser avec en javascript

Comment utiliser avec en javascript

青灯夜游
Libérer: 2022-03-28 16:49:21
original
1706 Les gens l'ont consulté

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...}".

Comment utiliser avec en javascript

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
}
Copier après la connexion
  • 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
};
Copier après la connexion

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;
Copier après la connexion

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;
}
Copier après la connexion

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被泄漏到全局作用域上
Copier après la connexion

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

Lorsque nous passons o1, l'opération d'affectation 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.

Mais pourquoi le fonctionnement d'o2 entraîne-t-il une fuite de données ?

Ici, nous devons revenir au mécanisme de 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

, une variable globale sera automatiquement créée dans le scope global), dans

en mode strict

, une exception ReferenceError 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

Comment utiliser avec en javascriptwith 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é

<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>
Copier après la connexion
Ensuite, l'effet de test :

🎜🎜Dans le code qui traite la même logique, le temps d'exécution sans with n'est que de 4,63 ms. La durée d'utilisation de with est de 81,87 ms. 🎜🎜Pourquoi est-ce ? 🎜🎜La raison est que le 🎜moteur JavaScript effectuera plusieurs optimisations de performances lors de la phase de compilation🎜. Certaines de ces optimisations reposent sur la capacité d'analyser statiquement le code en fonction de son lexique et de prédéterminer où toutes les variables et fonctions sont définies afin que les identifiants puissent être trouvés rapidement lors de l'exécution. 🎜🎜Mais si le moteur trouve with dans le code, il peut simplement supposer que tout jugement sur la position de l'identifiant est invalide, car il n'y a aucun moyen de savoir à quoi le contenu de l'objet passé a été utilisé pour créer le nouveau lexical. la portée est . 🎜

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 :

tutoriel vidéo javascript

, front-end web

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal