Caractéristiques dynamiques des fonctions JavaScript: auto-définition et réécriture
Points clés:
La nature dynamique du JavaScript signifie que les fonctions peuvent non seulement s'appeler, mais aussi se définir ou même se réécrire. Ceci est réalisé en attribuant des fonctions anonymes à des variables avec le même nom que la fonction.
Considérez la fonction suivante:
function party(){ console.log('Wow this is amazing!'); party = function(){ console.log('Been there, got the T-Shirt'); } }
Cette fonction publie d'abord un message à la console, puis se réécrit pour publier un message différent à la console. Lorsque la fonction est appelée une fois, elle est définie comme ceci:
function party() { console.log('Been there, got the T-Shirt'); }
Après le premier appel, chaque fois que la fonction est appelée, le message "a été là, a obtenu le t-shirt" sera sorti:
party(); party(); party();
Si la fonction est également attribuée à une autre variable, cette variable conservera la définition de la fonction d'origine et ne sera pas réécrite. En effet, la fonction d'origine est attribuée à une variable, puis à l'intérieur de la fonction, une variable avec le même nom que la fonction est attribuée à une autre fonction. Si nous créons une variable nommée avant le premier appel et redéfinir et l'attribuer à la fonction beachParty
, nous pouvons voir cet exemple: party()
function party(){ console.log('Wow this is amazing!'); party = function(){ console.log('Been there, got the T-Shirt'); } } const beachParty = party; // 注意,party 函数尚未被调用 beachParty(); // party() 函数现在已被重定义,即使它没有被显式调用 party(); beachParty(); // 但此函数尚未被重定义 beachParty(); // 无论调用多少次,它都将保持不变
et voir qu'il n'existe plus après que la fonction est appelée et redéfinie: music
function party() { console.log('Wow this is amazing!'); party = function(){ console.log('Been there, got the T-Shirt'); } } party.music = 'Classical Jazz'; // 设置函数的属性 party(); party.music; // 函数现在已被重定义,因此属性不存在
Cette technique peut être utilisée avec la détection des fonctionnalités dont nous avons discuté dans le chapitre précédent pour créer des fonctions qui se réécrivent, appelées branches d'initiés. Cela permet à la fonction de fonctionner plus efficacement dans le navigateur et évite de vérifier les fonctionnalités à chaque fois qu'il est appelé.
Prenons notre objet de licorne fictif, qui n'est pas entièrement pris en charge dans tous les navigateurs. Dans le chapitre précédent, nous avons examiné comment utiliser la détection des fonctionnalités pour vérifier si cette fonctionnalité est prise en charge. Maintenant, nous pouvons aller plus loin: nous pouvons définir des fonctions en fonction de la prise en charge de certaines méthodes. Cela signifie que nous n'avons besoin de vérifier le support que lorsque la fonction est appelée la première fois:
function party(){ console.log('Wow this is amazing!'); party = function(){ console.log('Been there, got the T-Shirt'); } }
Après avoir vérifié si l'objet window.unicorn
existe (en vérifiant s'il s'agit d'une vraie valeur), nous remplacons la fonction ride()
en fonction du résultat. À la fin de la fonction, nous l'appelons à nouveau afin que la fonction réécrite soit maintenant appelée et que la valeur pertinente soit renvoyée. Il convient de noter que la fonction est appelée deux fois la première fois, bien qu'elle devienne plus efficace avec chaque appel ultérieur. Voyons comment cela fonctionne:
function party() { console.log('Been there, got the T-Shirt'); }
Une fois la fonction appelée, il sera réécrit en fonction des fonctions du navigateur. Nous pouvons vérifier cela en vérifiant la fonction sans l'appeler:
Cela peut être un modèle utile pour initialiser les fonctions lorsqu'ils sont appelés la première fois et les optimiser pour le navigateur utilisé.
La fonction récursive fait référence à une fonction qui s'appelle jusqu'à ce qu'une certaine condition soit remplie. C'est un outil utile en ce qui concerne les processus itératifs. Un exemple courant est une fonction qui calcule un numéro factoriel:
party(); party(); party();
Si 0 est fourni comme l'argument (0 est factorisé 1), cette fonction renvoie 1, sinon elle multipliera l'argument par le résultat de s'appeler avec un paramètre de moins que lui. La fonction continuera de s'appeler jusqu'à ce que le paramètre final soit 0 et renvoie 1. Cela entraînera une multiplication de 1, 2, 3 et tous les nombres jusqu'au paramètre d'origine.
Un autre exemple du domaine des mathématiques est la conjecture Collatz. Il s'agit d'une question simple à énoncer, mais n'a pas été résolu jusqu'à présent. Il s'agit de prendre tout entier positif et de suivre les règles suivantes:
Par exemple, si nous commençons par le numéro 18, nous obtiendrons la séquence suivante:
18, 9, 28, 14, 7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1 , 4, 2, 1,…
Comme vous pouvez le voir, la séquence finit par tomber dans une boucle, en boucle à travers "4,2,1". La conjecture Collatz indique que chaque entier positif crée une séquence qui se termine par cette boucle. Cela a été vérifié pour tous les nombres jusqu'à 5 × 2⁶⁰, mais il n'y a aucune preuve qu'il continuera de conserver tous les entiers au-dessus de cela. Pour tester cette conjecture, nous pouvons écrire une fonction qui utilise la récursivité pour continuer à appeler la fonction jusqu'à ce qu'elle atteigne la valeur 1 (parce que nous voulons que notre fonction évite de finir par tomber dans une boucle récursive!):
function party(){ console.log('Wow this is amazing!'); party = function(){ console.log('Been there, got the T-Shirt'); } }
Cette fonction prend un nombre comme argument, et un autre argument nommé sequence
, avec une valeur par défaut d'un tableau contenant le premier argument. Le deuxième paramètre n'est utilisé que lorsque la fonction s'appelle récursivement.
est de tester si la valeur de n
est 1. Si c'est le cas, la fonction renvoie un message indiquant le nombre de pas qu'il a pris. S'il n'atteint pas 1, il vérifie si la valeur de n
est un nombre uniforme (dans ce cas, il le divise par 2), ou un nombre impair, dans ce cas, il se multiplie par 3 et ajoute 1. La fonction s'appelle ensuite, fournissant une nouvelle valeur n
et une nouvelle séquence en tant que paramètres. Une nouvelle séquence est construite en plaçant l'ancienne séquence et les valeurs de n
dans un nouveau tableau et en appliquant l'opérateur d'extension à l'ancienne séquence.
Voyons ce qui se passe avec le numéro 18:
function party() { console.log('Been there, got the T-Shirt'); }
Comme vous pouvez le voir, il faut 21 étapes, mais finalement il se termine à 1.
Essayez d'utiliser cette fonction et voyez si vous pouvez trouver une valeur supérieure à 5 × 2⁶⁰ qui ne se termine pas à 1 - si vous le faites, vous deviendrez célèbre!
Dans JavaScript, vous pouvez utiliser le constructeur Function
pour créer des fonctions dynamiquement. Ce constructeur prend deux paramètres: une chaîne contenant une liste de noms de paramètres séparée par des virgules et une chaîne contenant le corps de la fonction. Par exemple, vous pouvez créer une fonction qui ajoute deux nombres, comme ceci:
party(); party(); party();
Cette méthode vous permet de définir les fonctions dynamiquement, mais elle n'est généralement pas recommandée car elle n'est pas aussi efficace et sujette aux erreurs que la déclaration normale des fonctions.
Dans JavaScript, les fonctions peuvent être auto-définies, ce qui signifie qu'ils peuvent modifier leur propre code lors de l'exécution. Cela est possible car les fonctions dans JavaScript sont des objets de première classe, ce qui signifie qu'ils peuvent être transmis, renvoyés d'autres fonctions et même modifiés. Voici un exemple d'une fonction se réécrivant:
function party(){ console.log('Wow this is amazing!'); party = function(){ console.log('Been there, got the T-Shirt'); } } const beachParty = party; // 注意,party 函数尚未被调用 beachParty(); // party() 函数现在已被重定义,即使它没有被显式调用 party(); beachParty(); // 但此函数尚未被重定义 beachParty(); // 无论调用多少次,它都将保持不变
La première fois que foo()
est appelé, il se réécrit. La prochaine fois que foo()
s'appelle, il exécutera le nouveau code.
Dans JavaScript, vous pouvez remplacer la fonction en attribuant simplement une nouvelle fonction à la même variable. Voici un exemple:
function party() { console.log('Wow this is amazing!'); party = function(){ console.log('Been there, got the T-Shirt'); } } party.music = 'Classical Jazz'; // 设置函数的属性 party(); party.music; // 函数现在已被重定义,因此属性不存在
Lorsque vous appelez foo()
, il exécute la nouvelle fonction, pas la fonction d'origine. En effet, la variable foo
pointe désormais la nouvelle fonction.
Définition dynamique Les fonctions JavaScript peuvent fournir une flexibilité car vous pouvez créer et modifier dynamiquement les fonctions en fonction des besoins de votre programme. Cependant, il a également des inconvénients. Il n'est pas aussi efficace que de déclarer les fonctions normalement, car le moteur JavaScript ne peut pas optimiser les fonctions à l'avance. Il est également plus sujet aux erreurs, car aucune erreur dans la chaîne de corps de fonction n'est capturée avant l'exécution de la fonction.
Oui, vous pouvez utiliser les fonctions Arrow pour définir et remplacer les fonctions JavaScript. Les fonctions Arrow fournissent une syntaxe plus propre et ont des différences dans la manipulation de ce mot et d'autres mots clés spéciaux. Voici un exemple de définition et de réécriture des fonctions de flèche:
function party(){ console.log('Wow this is amazing!'); party = function(){ console.log('Been there, got the T-Shirt'); } }
Lorsque vous appelez foo()
, il exécute la nouvelle fonction, pas la fonction d'origine.
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!