Maison  >  Article  >  interface Web  >  Comment écrire du code JS de haute qualité_Connaissances de base

Comment écrire du code JS de haute qualité_Connaissances de base

WBOY
WBOYoriginal
2016-05-16 16:23:541002parcourir

Je souhaite écrire une bibliothèque JavaScript efficace mais je ne sais pas par où commencer

J’ai essayé de lire les bibliothèques de classe d’autres personnes, mais il me semblait les comprendre

 ;

Je prévois d'étudier les fonctions avancées de js, mais le contenu du livre faisant autorité est trop dispersé,

Même si je me souviens de "l'usage", je ne pense pas à la "méthode" lorsqu'il s'agit de "l'utiliser".

Peut-être que vous êtes comme moi, il semble y avoir une force invisible qui contraint nos plans, nous faisant penser à plusieurs reprises aux limites de la connaissance, nous obligeant à rester immobiles et à avoir du mal à avancer.

Pendant cette période, la pression a doublé en raison des divers devoirs, conceptions de cours et rapports expérimentaux. Il est rare de prendre un peu de temps, de ne jamais dormir, d'organiser et de résumer les livres que j'ai lus dans le passé, juste pour me rapprocher de l'écriture de ma propre bibliothèque de classe.

Cet article fait référence à "Javascript Language Essence" et "Effective JavaScript". Les exemples ont été débogués, et après les avoir compris, je souhaite simplifier un peu certains principes « profonds ».

1. Portée variable

Scope est comme de l'oxygène pour les programmeurs. Il y en a partout et souvent on n'y pense même pas. Mais lorsqu'il est pollué (par exemple en utilisant des objets globaux), on peut se sentir étouffé (par exemple l'application devient moins réactive). Les règles de portée principales de JavaScript sont simples, bien conçues et puissantes. Utiliser efficacement JavaScript nécessite de maîtriser certains concepts de base de portée variable et de comprendre certains cas extrêmes qui peuvent conduire à des problèmes insaisissables et désagréables.

1.1 Utiliser le moins possible les variables globales

Javascript facilite la création de variables dans l'espace de noms global. La création d'une variable globale se fait sans effort car elle ne nécessite aucune forme de déclaration et est automatiquement accessible par tout le code tout au long du programme.

Pour les débutants comme nous, lorsque nous rencontrons certains besoins (par exemple, les données transmises sont enregistrées, utilisées en attendant qu'une certaine fonction soit appelée à un certain moment ; ou qu'une certaine fonction est fréquemment utilisée), nous ne le faisons pas hésite à penser aux fonctions globales, ou même au langage C que j'ai appris au cours de ma première année, qui est trop profondément enraciné dans la pensée orientée processus, et le système est parfaitement plein de fonctions. La définition de variables globales pollue l'espace de noms public partagé et peut entraîner des conflits de noms inattendus. Les variables globales sont également préjudiciables à la modularité car elles conduisent à un couplage inutile entre les composants indépendants d'un programme. Sérieusement, trop de globaux (y compris des feuilles de style, définissant directement le style de div ou a) deviendront une erreur catastrophique une fois intégrés dans un processus de développement multi-personnes. C'est pourquoi tout le code de jQuery est enveloppé dans une expression anonyme qui s'exécute immédiatement - une fonction anonyme auto-appelante. Lorsque le navigateur charge le fichier jQuery, la fonction anonyme auto-appelante commence immédiatement à s'exécuter et initialise chaque module de jQuery pour éviter d'endommager et de contaminer les variables globales et d'affecter d'autres codes.

Copier le code Le code est le suivant :

(fonction(fenêtre,non défini){
var jQuery = ...
//...
​ window.jQuery = window.$ = jQuery;
})(fenêtre);

De plus, vous pensez peut-être qu'il est plus pratique « d'écrire comme vous voulez d'abord et de l'organiser plus tard », mais les bons programmeurs prêteront constamment attention à la structure du programme, continueront à classer les fonctions associées et sépareront les composants non pertinents. . et incluez ces comportements dans le cadre du processus de programmation.

Étant donné que l'espace de noms global est le seul moyen d'interagir entre les composants indépendants d'un programme JavaScript, l'utilisation de contrôles nommés globalement est inévitable. Les composants ou bibliothèques doivent définir des variables globales. pour être utilisé par d'autres parties du programme. Sinon, il vaut mieux utiliser des variables locales.

Copier le code Le code est le suivant :

this.foo ;//undéfini
foo = "foo global";
this.foo ;//"global foo"
var foo = "global foo";
this.foo = "changé";
foo ;//changé

L'espace de noms global de JavaScript est également exposé à un objet global accessible dans la portée globale du programme, qui sert de valeur initiale du mot-clé this. Dans les navigateurs Web, les objets globaux sont liés à la variable globale window. Cela signifie que vous avez deux manières de créer une variable globale : la déclarer en utilisant var dans la portée globale ou l'ajouter à l'objet global. L'avantage d'utiliser la déclaration var est qu'elle peut exprimer clairement l'impact des variables globales dans la portée du programme.

Étant donné que les références à des variables globales liées peuvent provoquer des erreurs d'exécution, garder les portées claires et concises permettra aux utilisateurs de votre code de comprendre plus facilement quelles variables globales déclarent le programme.

Étant donné que l'objet global fournit un mécanisme de réponse dynamique pour l'environnement global, vous pouvez l'utiliser pour interroger un environnement en cours d'exécution et détecter quelles fonctionnalités sont disponibles sur cette plate-forme.

eg.ES5 introduit un objet JSON global pour lire et écrire des données au format JSON.

Copier le code Le code est le suivant :

si(!this.JSON){
Ceci.JSON = {
           analyser : ..,
          stringifier : ...                          }  
>

Si vous fournissez une implémentation JSON, vous pouvez bien entendu utiliser votre propre implémentation de manière simple et inconditionnelle. Mais les implémentations intégrées fournies par l'environnement d'hébergement sont presque plus adaptées car elles sont écrites en C dans le navigateur. Parce qu’ils sont rigoureusement vérifiés pour leur exactitude et leur cohérence par rapport à certaines normes, et qu’ils offrent généralement de meilleures performances que les implémentations tierces.

La conception originale du cours sur la structure des données simulait les opérations de base des chaînes, exigeant que les méthodes fournies par le langage lui-même ne puissent pas être utilisées. JavaScript implémente très bien les opérations de base sur les tableaux. Si c'est juste pour des besoins généraux d'apprentissage, l'idée de simuler les méthodes fournies par le langage lui-même est bonne, mais si vous investissez vraiment dans le développement, ce n'est pas nécessaire. pensez à utiliser les méthodes intégrées de JavaScript en premier lieu.

1.2 Évitez d'utiliser avec

L'instruction with fournit toute "commodité" qui rend votre application peu fiable et inefficace. Nous devons appeler une série de méthodes sur un seul objet en séquence. L'utilisation de l'instruction with peut facilement éviter les références répétées aux objets :

Copier le code Le code est le suivant :
état de la fonction (info){
var widget = nouveau widget();
avec(widget){
             setBackground("blue");
             setForeground("blanc");
             setText("Statut : " info);
show();
}  
>

Il est également tentant d'"importer" des variables à partir d'objets de module à l'aide de l'instruction with.

Copier le code Le code est le suivant :
fonction f(x,y){
avec(Mathématiques){
           return min(round(x),sqrt(y));//Référence abstraite
>
>

En fait, JavaScript traite toutes les variables de la même manière. JavaScript recherche des variables en partant de la portée la plus interne et en allant vers l'extérieur. Le langage with traite un objet comme s'il représentait une portée de variable, donc dans un bloc with, la recherche de variable commence par la recherche des propriétés du nom de variable donné. Si la propriété n'est pas trouvée dans cet objet, la recherche se poursuit dans la portée externe. Chaque référence à une variable externe dans un bloc with suppose implicitement qu'il n'y a pas de propriété du même nom dans l'objet with (et dans aucun de ses objets prototypes). La création ou la modification de l'objet with ou de son objet prototype ailleurs dans le programme ne suit pas nécessairement cette hypothèse. Bien entendu, le moteur JavaScript ne lira pas le code local pour savoir quelles variables locales vous utilisez. Les étendues JavaScript peuvent être représentées comme des structures de données internes efficaces, et les recherches de variables peuvent être très rapides. Cependant, comme le bloc de code with doit rechercher la chaîne prototype de l'objet pour trouver toutes les variables du code with, sa vitesse d'exécution est beaucoup plus lente que celle des blocs de code ordinaires.

Au lieu d'utiliser le langage, le moyen le plus simple consiste à lier l'objet à un nom de variable court.

Copier le code Le code est le suivant :

état de la fonction (info){
var w = nouveau Widget();
 
w.setBackground("bleu");
w.setForeground("blanc");
              w.setText("Statut : " info);
w.show();

>

Dans d'autres cas, la meilleure approche consiste à lier explicitement la variable locale à la propriété appropriée.

Copier le code Le code est le suivant :

fonction f(x,y){
var min = Math.min,
tour = Math.tour,
          sqrt   = Math.sqrt;                                       Retour min(round(x),sqrt(y));
>

1.3 Maîtrise des fermetures

Il existe un seul concept pour comprendre les fermetures :

a) JavaScript vous permet de référencer des variables définies en dehors de la fonction actuelle.

Copier le code Le code est le suivant :
fonction makeSandwich(){
var magicIngredient = "beurre de cacahuète";
fonction make(filling){
         return magicIngredient " et " remplissage ;
>
Retour make("gelée");
>
makeSandwich();// "beurre de cacahuète et gelée"

b) Même si la fonction externe est revenue, la fonction actuelle peut toujours référencer les variables définies dans la fonction externe

Copier le code Le code est le suivant :
fonction makeSandwich(){
var magicIngredient = "beurre de cacahuète";
fonction make(filling){
         return magicIngredient " et " remplissage ;
>
Retourner la marque ;
>
var f = sandwichMaker();
f("gelée");                                                                                                                                                                                                                                             // "beurre de cacahuète et gelée"
f("bananes");                         // "beurre de cacahuète et bananes"
f("mauves");                          // "beurre de cacahuète et mauves"

Les valeurs des fonctions javascriptd contiennent plus d'informations que le code requis pour s'exécuter lorsqu'elles sont appelées. De plus, les valeurs des fonctions JavaScript stockent également en interne les variables auxquelles elles peuvent faire référence et qui sont définies dans leur portée englobante. Les fonctions qui assurent le suivi des variables dans le cadre qu'elles couvrent sont appelées fermetures.

La fonction make est une fermeture, et son code fait référence à deux variables externes : magicIngredient et fill. Chaque fois que la fonction make est appelée, son code peut référencer ces deux variables car la fermeture stocke ces deux variables.

Une fonction peut référencer n'importe quelle variable dans sa portée, y compris les paramètres et les variables de fonction externes. Nous pouvons en profiter pour écrire une fonction sandwichMaker plus générale.

Copier le code Le code est le suivant :
fonction makeSandwich(magicIngredient){
fonction make(filling){
         return magicIngredient " et " remplissage ;
>
Retourner la marque ;
>
var f = sandwichMaker("jambon");
f("fromage");                                   // "jambon et fromage"
f("moutarde");                                     // "jambon et moutarde"

Les fermetures sont l’une des fonctionnalités les plus élégantes et expressives de JavaScript et sont au cœur de nombreux idiomes.

c) Les fermetures peuvent mettre à jour la valeur des variables externes. En fait, les fermetures stockent des références à des variables externes, pas des copies de leurs valeurs. Par conséquent, des mises à jour peuvent être effectuées pour toute fermeture ayant accès à ces variables externes.

Copier le code Le code est le suivant :

boîte de fonction(){
var val = indéfini;
Retour {
​​​​​ set : function(newval) {val = newval;},
             obtenir : function (){return val;},
         tapez : function(){return typeof val;}
};
>
var b = boîte();
b.type(); //non défini
b.set(98.6);
b.get();//98.6
b.type();//numéro

Cet exemple produit un objet contenant trois fermetures. Ces trois fermetures sont des propriétés set, type et get. Elles partagent toutes l'accès à la variable val. La fermeture set met à jour la valeur de val. Appelez ensuite get et tapez pour afficher les résultats mis à jour.

1.4 Comprendre les améliorations de la déclaration des variables

Javascript prend en charge cette méthode de portée (la référence à la variable foo sera liée à la portée la plus proche de la déclaration de la variable foo), mais ne prend pas en charge la portée au niveau du bloc (la portée de la définition de la variable n'est pas la portée englobante la plus proche) ou bloc de code).

Ne pas comprendre cette fonctionnalité entraînera quelques bugs subtils :

Copier le code Le code est le suivant :

la fonction estGagnant(joueur,autres){
var le plus élevé = 0;
pour(var je = 0,n = autres.longueur ;i            var joueur = autres[i];
Si (player.score > le plus élevé) {
                                                                                                                                                                   le plus élevé = joueur.score ;           }
>
Renvoie player.score > le plus élevé ;
>

1.5 Méfiez-vous de la portée maladroite des expressions de fonctions nommées

Copier le code Le code est le suivant :
fonction double(x){ return x*2; }
var f = fonction(x){ return x*2 }

Le même code de fonction peut également être utilisé comme expression, mais il a des significations complètement différentes. La différence officielle entre les fonctions anonymes et les expressions de fonctions nommées est que ces dernières sont liées à une variable portant le même nom de fonction qu'une variable locale de la fonction. Cela peut être utilisé pour écrire des expressions de fonctions récursives.

Copier le code Le code est le suivant :
var f = fonction trouver (arbre, clé){
//....
Retour find(tree.left, key) ||
                    find(tree.right,key);                                                   >


Il convient de noter que la portée de la variable find se situe uniquement dans sa propre fonction. Contrairement aux déclarations de fonction, les expressions de fonction nommées ne peuvent pas être référencées en externe via leurs noms de fonction internes.

find(myTree,"foo");//erreur : find n'est pas défini
var constructeur = function(){ return null; }
var f= fonction(){
Renvoie le constructeur();
};
f();//{}(dans les environnements ES3)

Ce programme semble générer null, mais il générera en fait un nouvel objet.

Étant donné que la portée de la variable de fonction nommée hérite de Object.prototype.constructor (c'est-à-dire le constructeur de Object), tout comme l'instruction with, cette portée sera affectée par le changement dynamique de Object.prototype. Le moyen d'éviter que les objets ne polluent la portée des expressions de fonction dans votre système est d'éviter d'ajouter des propriétés à Object.prototype à tout moment et d'éviter d'utiliser des variables locales portant le même nom que les propriétés Object.prototype standard.

Une autre lacune des moteurs JavaScript populaires est la promotion des déclarations d'expressions de fonctions nommées.

Copier le code Le code est le suivant :

var f = fonction g(){retour 17;}
g(); //17 (dans un environnement non conforme)

Certains environnements JavaScript traitent même les deux fonctions f et g comme des objets différents, ce qui entraîne une allocation de mémoire inutile.

1.6 Méfiez-vous des déclarations de portée maladroites pour les fonctions de bloc locales

Copier le code Le code est le suivant :

fonction f() {retour "global" ; }
test de fonction(x){
Fonction f(){return "local";}
var résultat = [];
Si(x){
          result.push(f());
}  
résultat.push(f());
résultat résultat ;
>
test(vrai); //["local","local"]
test(faux); //["local"]

Copier le code Le code est le suivant :

fonction f() {retour "global" ; }
test de fonction(x){
var résultat = [];
Si(x){
           fonction f(){return "local";}
          result.push(f());
}  
résultat.push(f());
résultat résultat ;
>
test(vrai); //["local","local"]
test(faux); //["local"]

Javascript n'a pas de portée au niveau du bloc, donc la portée de la fonction interne f doit être la fonction de test entière. Cela est vrai pour certains environnements JavaScript, mais toutes les implémentations JavaScript ne signalent pas ces fonctions comme des erreurs en mode strict (un programme en mode strict avec une déclaration de fonction de bloc locale le signalera comme une erreur de syntaxe). -code portable et donne une sémantique plus sensible et plus fiable aux déclarations de fonctions de bloc locales pour les futures versions de la norme. Pour cette situation, vous pouvez envisager de déclarer une variable locale dans la fonction de test pointant vers la fonction globale f.

Déclaration:
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