Maison >interface Web >js tutoriel >Explication détaillée des fonctions JavaScript_Connaissances de base

Explication détaillée des fonctions JavaScript_Connaissances de base

WBOY
WBOYoriginal
2016-05-16 16:31:141296parcourir

Présentation

Dans de nombreux langages traditionnels (C/C/Java/C#, etc.), les fonctions existent en tant que citoyens de seconde classe. Vous ne pouvez déclarer une fonction qu'à l'aide de mots-clés du langage, puis l'appeler si vous avez besoin d'utiliser le. fonction comme paramètre Pour le passer à une autre fonction, l'affecter à une variable locale ou l'utiliser comme valeur de retour, vous devez passer par des méthodes spéciales telles que le pointeur de fonction et le délégué.
Dans le monde JavaScript, les fonctions sont des citoyens de première classe. Elles disposent non seulement de tous les moyens d'utiliser les fonctions traditionnelles (déclaration et appel), mais peuvent également attribuer des valeurs, transmettre des paramètres et renvoyer des valeurs simples. Ces fonctions sont également appelées troisièmes. -fonctions de classe. De plus, la fonction en JavaScript agit également en tant que constructeur de la classe et est une instance de la classe Function. De telles identités multiples rendent les fonctions JavaScript très importantes.

1. Fonctions JavaScript d'entrée de gamme

Comme d'autres langages, les fonctions JavaScript suivent d'abord le principe de déclaration et sont utilisées ultérieurement. Les noms de fonctions ne peuvent contenir que des lettres, des chiffres, des traits de soulignement ou $, et ne peuvent pas commencer par des chiffres. Il existe deux manières courantes de déclarer des fonctions :

Copier le code Le code est le suivant :

// Déclarez directement la fonction myfunc
function myfunc(/* arguments */) {
}

//Attribuer la fonction anonyme à la variable locale myfunc
var myfunc = function(/* arguments */) {
}

Notez qu'il existe des différences subtiles entre les deux méthodes de déclaration de fonction ci-dessus : la première méthode est une fonction nommée lorsqu'elle est déclarée, qu'elle soit déclarée avant l'appel, après l'appel ou même dans une position qui ne sera pas exécutée (comme une instruction return ou dans une branche qui ne sera jamais vraie), sont accessibles dans toute la portée ; la deuxième façon consiste à attribuer une fonction anonyme à une variable, qui n'est pas strictement une déclaration de fonction (déclaration de fonction) est une fonction expression. Cette fonction n'est accessible par aucun code avant l'affectation, ce qui signifie que l'affectation doit être terminée avant l'appel, sinon une erreur se produira lors de l'appel : "TypeError : undefined n'est pas une fonction". Par exemple :

Copier le code Le code est le suivant :

myfunc1(); // Peut être appelé normalement car myfunc1 est déclaré directement

function myfunc1() {
}

myfunc2(); // Erreur TypeError : undéfini n'est pas une fonction

var myfunc2 = function() {
};


La méthode de base pour appeler une fonction est la même que dans les langages traditionnels utilisant une paire de parenthèses : myfunc(). Les fonctions JavaScript prennent également en charge les appels récursifs directs ou indirects. Par exemple, la fonction Fibonacci classique peut être implémentée en JavaScript comme ceci : .

Copier le code Le code est le suivant :

fonction fib(n) {
Si (n == 1 || n == 2) {
Renvoyez 1 ;
} autre {
Renvoie fib(n - 2) fib(n - 1); }
>

Les fonctions en JavaScript peuvent gérer des paramètres de longueur variable. À l'intérieur de la fonction, il y a une variable locale nommée arguments, qui est un objet de type tableau qui contient tous les paramètres transmis lors de l'appel. . Par exemple :

Copier le code Le code est le suivant :
fonction test() {
alert(arguments.length);
}

test(1); // 1
test(1, 'une'); // 2
test(true, [], {}); // 3 Les arguments peuvent être utilisés pour implémenter des fonctions similaires au langage C printf, et peuvent également être utilisés pour implémenter le polymorphisme de méthode.

2. Fonctions JavaScript avancées

2.1 Fonctions anonymes et fonctions imbriquées

En JavaScript, vous pouvez déclarer une fonction sans nom, appelée fonction anonyme. Dans le même temps, JavaScript permet également de déclarer des fonctions à l'intérieur de fonctions, appelées fonctions imbriquées. La portée d'une fonction imbriquée est la fonction parent entière.

Dans la section de déclaration de fonction précédente, nous avons vu une utilisation de fonctions anonymes et de fonctions imbriquées. Puisque les fonctions anonymes n'ont pas de nom, elles n'introduiront pas de nouvelles variables pour polluer le contexte et apporteront donc de nouvelles portées de variables. utilisé pour prévenir la pollution de l’environnement mondial.

Il existe un environnement global spécial (objet global) dans le runtime JavaScript. Cet objet stocke des fonctions et des variables globales. Dans le développement réel, plusieurs bibliothèques tierces ou plusieurs fichiers js sont souvent utilisés si vous introduisez accidentellement une duplication dans l'objet global Variable. ou une déclaration de fonction entraînera une confusion dans l'exécution du code. Par exemple, deux fichiers js sont introduits l'un après l'autre et chacun définit son propre journal de fonction pour un usage interne. La deuxième fonction introduite écrasera la première définition et ne générera aucune erreur. L'appel de la fonction log lors des exécutions ultérieures peut causer des problèmes. provoquant des erreurs. À l'heure actuelle, l'utilisation d'une fonction anonyme pour envelopper la logique dans l'intégralité du js peut éviter cette erreur. Cette méthode a été utilisée par la plupart des bibliothèques js open source.

Copier le code Le code est le suivant :

(function() { // Fonction anonyme

journal de fonction (msg) {
console.log(msg);
}

// Autres codes

}()); // Exécuter immédiatement

Le code ci-dessus est un exemple simple. La portée de la fonction log est limitée à cette fonction anonyme, et la fonction anonyme est entourée d'une paire de parenthèses () à l'extérieur pour former une expression de fonction. fonction, suivi d'une paire de parenthèses pour indiquer que la fonction sera exécutée immédiatement, permettant au code d'origine d'être exécuté normalement. Cependant, les fonctions déclarées de cette manière, les variables déclarées via var, etc. sont internes et ne sont accessibles par aucun code autre que les fonctions anonymes. Si vous devez exposer certaines fonctions en tant qu'interfaces, il existe plusieurs méthodes :

Copier le code Le code est le suivant :

var malib = (fonction (globale) {

journal de fonction (msg) {
console.log(msg);
}

log1 = log; // Méthode 1 : Utiliser le comportement par défaut de déclaration de variable sans var et faire de log1 une variable globale (non recommandé)

global.log2 = log; // Méthode 2 : Ajouter l'attribut log2 directement à l'objet global et attribuer la valeur à la fonction log (recommandé)

return { // Méthode 3 : obtenez une série d'objets de collection de fonctions d'interface via la valeur de retour de la fonction anonyme et affectez-les à la variable globale mylib (recommandé)
Journal : journal
};

}(fenêtre));

2.2 Fonction d'ordre élevé

Si une fonction est utilisée comme paramètre ou valeur de retour, elle est appelée fonction d'ordre supérieur. Toutes les fonctions en JavaScript peuvent être utilisées comme fonctions d'ordre supérieur. C'est également une caractéristique du premier type de fonction. Ci-dessous, nous analyserons respectivement ces deux méthodes d’utilisation.

Copier le code Le code est le suivant :

fonction négative(n) {
Return -n; // Prend la valeur opposée de n
}

fonction carré(n) {
Renvoie n*n ; // n au carré
}

function process (numéros, rappel) {
var résultat = [];

for(var i = 0, length = nums.length; i < length; i ) {
result[i] = callback(nums[i]); // Passe tous les éléments du tableau nums au rappel pour traitement et enregistre la valeur de retour comme résultat
}

Retourner le résultat ;
}

var nums = [-3, -2, -1, 0, 1, 2, 3, 4]; var n_neg = process(nums, négatif);
// n_neg = [3, 2, 1, 0, -1, -2, -3, -4]; var n_square = process(nums, carré);
// n_square = [9, 4, 1, 0, 1, 4, 9, 16];

Le code ci-dessus montre un exemple de passage d'une fonction en tant que paramètre dans un autre appel de processus de fonction. Dans l'implémentation de la fonction de processus, le rappel est traité comme une boîte noire, chargée de lui transmettre les paramètres, puis d'obtenir. la valeur de retour. L'implémentation spécifique du rappel n'était pas claire auparavant. Ce n'est que lorsque les lignes 20 et 22 sont exécutées que le rappel est représenté respectivement par un négatif ou un carré, et l'opération de valeur opposée ou carrée est effectuée sur chaque élément respectivement.

Copier le code Le code est le suivant :

générateur de fonctions() {
var je = 0;
Fonction de retour() {
Rends-moi
};
}

var gen1 = generateur(); // Obtenez un générateur de nombres naturels
var gen2 = generateur(); // Obtenez un autre générateur de nombres naturels
var r1 = gen1(); // r1 = 0
var r2 = gen1(); // r2 = 1
var r3 = gen2(); // r3 = 0
var r4 = gen2(); // r4 = 1

Le code ci-dessus montre un exemple d'utilisation d'une fonction comme générateur de valeur de retour est une fonction génératrice de nombres naturels, et la valeur de retour est une fonction génératrice de nombres naturels. Chaque fois que le générateur est appelé, une fonction anonyme est renvoyée comme résultat. Cette fonction anonyme renvoie tour à tour chaque nombre naturel lorsqu'elle est réellement appelée. La variable i dans le générateur augmentera de 1 à chaque appel de cette fonction anonyme. Il s'agit en fait d'une fermeture. Présentons les fermetures ci-dessous.


2.3 Fermeture
La fermeture (Closure) n'est pas un concept nouveau. Les fermetures sont utilisées dans de nombreux langages fonctionnels. En JavaScript, les fermetures sont utilisées lorsque vous utilisez des variables dans le cadre d'une fonction externe au sein d'une fonction en ligne. Utilisez une analogie courante pour expliquer la relation entre les fermetures et les classes : les classes sont des données avec des fonctions et les fermetures sont des fonctions avec des données.
Une caractéristique des variables utilisées dans les fermetures est qu'elles ne sont pas libérées au retour de la fonction parent, mais se terminent à la fin du cycle de vie de la fermeture. Par exemple, comme l'exemple du générateur de la section précédente, gen1 et gen2 utilisent des variables indépendantes i (lorsque i de gen1 augmente de 1, i de gen2 n'est pas affecté, et vice versa), tant que gen1 ou gen2 Si les deux variables ne sont pas récupérés par le moteur JavaScript, leur variable respective i ne sera pas publiée. Dans la programmation JavaScript, les fermetures sont utilisées inconsciemment. Bien que cette fonctionnalité des fermetures apporte une facilité d'utilisation, elle peut aussi facilement causer des problèmes tels que des fuites de mémoire. Par exemple :

Copier le code Le code est le suivant :

var elem = document.getElementById('test');
elem.addEventListener('clic', function() {
alert('Vous avez cliqué sur ' elem.tagName);
});

La fonction de ce code est d'afficher le nom de l'étiquette d'un nœud lorsqu'il est cliqué. Il enregistre une fonction anonyme en tant que fonction de traitement d'événement de clic d'un nœud DOM. Un élément d'objet DOM est référencé dans la fonction, formant un. Sac fermé. Cela générera une référence circulaire, à savoir : DOM-> Closure->DOM-> Closure... L'objet DOM ne sera pas libéré avant la fermeture et la fermeture sert de fonction de gestion des événements du DOM ; L'objet existe, donc la fermeture ne sera pas libérée avant la libération de l'objet DOM. Même si l'objet DOM est supprimé dans l'arborescence DOM, en raison de l'existence de cette référence circulaire, ni l'objet DOM ni la fermeture ne seront libérés. Vous pouvez éviter cette fuite de mémoire en utilisant la méthode suivante :

Copier le code Le code est le suivant :

var elem = document.getElementById('test');
elem.addEventListener('clic', function() {
alert('Vous avez cliqué sur ' this.tagName); // Ne fait plus référence directement à la variable elem
});

Dans le code ci-dessus, this est utilisé à la place de elem (dans la fonction de gestion des événements DOM, le pointeur this pointe vers l'élément DOM lui-même), afin que le runtime JS ne pense plus que la variable de la classe parent est utilisée dans cette fonction, une fermeture n'est donc plus formée.
Les fermetures entraîneront également de nombreux problèmes de fuite de mémoire similaires. Faites uniquement attention aux fermetures lors de l'écriture du code pour essayer d'éviter de tels problèmes.

Constructeur de classe 2.4
Les fonctions JavaScript servent également de constructeurs de classes, donc tant que vous déclarez une fonction, vous pouvez utiliser le mot-clé new pour créer une instance de la classe.

Copier le code Le code est le suivant :

function Personne (nom) {
This.name = nom;
This.toString = function() {
Renvoyez 'Bonjour,' this.name '!'; };
}

var p = new Person('Ghostheaven'); alert(p); // Bonjour, Ghostheaven ! Dans l'exemple ci-dessus, la fonction Person est utilisée comme constructeur de la classe. À ce stade, elle pointe vers l'objet instance nouvellement créé. Vous pouvez ajouter des propriétés et des méthodes à l'instance. . Concernant la programmation JavaScript orientée objet détaillée, vous pouvez vous référer à cet article. Ce dont je veux parler ici, c'est du problème de la valeur de retour lorsque les fonctions JavaScript sont utilisées comme constructeurs de classe.


function MaClasse(nom) {
This.name = nom;
Nom de retour ; // Valeur de retour du constructeur ? }

var obj1 = new MaClasse('foo');
var obj2 = MaClasse('foo');
var obj3 = new MaClasse({});
var obj4 = MaClasse({});



Le constructeur ci-dessus est assez spécial, il a une instruction return, alors vers quels objets obj1~obj4 pointent-ils respectivement ? Le résultat réel est le suivant :

Copier le code Le code est le suivant : obj1 = Objet MaClasse
obj2 = 'foo'
obj3 = {}
obj4 = {}



La raison spécifique est expliquée dans cet article, et je n'entrerai pas dans les détails dans cet article. Puisque le constructeur avec une valeur de retour produira des résultats étranges, n'appelez pas une instruction return avec une valeur de retour dans le constructeur (un un retour à vide convient).


3. Niveau monstre de la fonction JavaScript

Bienvenue dans la zone d'enseignement des fonctions de niveau monstre, où nous vous apprendrons à affronter les monstres calmement et confortablement. . .

3.1 Classe de fonctions

Il existe une classe intégrée appelée Function dans le runtime JavaScript. Déclarer une fonction avec le mot-clé function est en fait une forme abrégée de création d'un objet de classe Function. Toutes les fonctions ont toutes les méthodes de la classe Function, telles que call, apply,. et bind. Attendez, vous pouvez vérifier cette déclaration via le mot-clé instanceof. Puisque Function est une classe, son constructeur est Function (lui-même est également un objet de la classe Function), et il devrait être possible de générer un objet fonction via le nouveau mot-clé. Voici le premier monstre, qui explique comment construire une fonction à l'aide de la classe Function. La syntaxe de Function est la suivante :

Copier le code Le code est le suivant : nouvelle fonction ([arg1[, arg2[, ... argN]],] functionBody)


Parmi eux, arg1, arg2, ... argN sont des chaînes, représentant les noms de paramètres, et functionBody est également une chaîne, représentant le corps de la fonction. Les noms de paramètres précédents peuvent être plus ou moins le constructeur de Function. dernier paramètre as Dans le corps de la fonction, les précédents sont traités comme des paramètres.

Copier le code Le code est le suivant : var func1 = new Function('name', 'return "Bonjour, " nom "!";'
); func1('Ghostheaven'); // Bonjour, Ghostheaven !



La méthode ci-dessus construit une fonction via Function. Cette fonction est exactement la même que les autres fonctions déclarées avec le mot-clé function.
Voyant cela, beaucoup de gens peuvent se demander pourquoi un tel monstre est nécessaire ? "Tout ce qui existe est raisonnable." La classe Function a son utilité unique. Vous pouvez l'utiliser pour générer dynamiquement diverses logiques de fonction, ou remplacer la fonction de la fonction eval, et empêcher la pollution de l'environnement actuel*.



3.2 Fonction d'auto-mise à jour

Dans de nombreux langages, une fois qu'une fonction est déclarée, elle ne peut pas déclarer à nouveau une fonction portant le même nom, sinon une erreur de syntaxe se produira. Cependant, les fonctions en JavaScript peuvent non seulement être déclarées à plusieurs reprises, mais également se mettre à jour. Le monstre qui se mange tout seul est là !

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