Maison > interface Web > js tutoriel > Fonctions javascript qui se définissent et se réécrivent

Fonctions javascript qui se définissent et se réécrivent

Christopher Nolan
Libérer: 2025-02-16 08:41:09
original
480 Les gens l'ont consulté

Caractéristiques dynamiques des fonctions JavaScript: auto-définition et réécriture

JavaScript Functions That Define and Rewrite Themselves

Points clés:

  • La nature dynamique de JavaScript permet aux fonctions de se définir ou même de se réécrire. Cela se fait en affectant une fonction anonyme à une variable avec le même nom que la fonction. Ce concept est appelé modèle de définition paresseux et peut être utilisé pour le code d'initialisation requis uniquement sur le premier appel de fonction.
  • Si la fonction est attribuée à une autre variable avant le premier appel et la redéfinition ultérieure, la nouvelle variable conservera la définition de la fonction d'origine et ne sera pas réécrite. Cependant, toutes les propriétés définies avant la redéfinition de la fonction seront perdues.
  • La technologie de réécriture des fonctions peut être combinée avec la détection des fonctionnalités pour créer des fonctions plus efficaces, un concept appelé branchement init-temps. Cela permet d'optimiser les fonctions pour que le navigateur soit utilisé, vérifiant la prise en charge des fonctionnalités uniquement lors du premier appel de fonction.

JavaScript Functions That Define and Rewrite Themselves

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

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

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

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(); // 无论调用多少次,它都将保持不变
Copier après la connexion
Copier après la connexion
Les propriétés sont manquantes

Méfiez-vous: si des propriétés ont été définies sur la fonction avant, ces propriétés seront perdues lorsque la fonction se remplace. Dans l'exemple précédent, nous pouvons définir une propriété

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; // 函数现在已被重定义,因此属性不存在
Copier après la connexion
Copier après la connexion
Ceci est appelé le modèle de définition paresseux et est généralement utilisé lorsque un code d'initialisation est requis lors du premier appel. Cela signifie que l'initialisation peut être effectuée sur le premier appel, puis la fonction peut être redéfinie comme la fonction que vous souhaitez utiliser avec chaque appel ultérieur.

Branche d'initiés (branchement init-temps)

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

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

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é.

fonction récursive

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

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:

  • Si le nombre est un nombre pair, divisez-le par deux
  • Si le nombre est un nombre impair, multipliez-le par trois et ajoutez un

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

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.

La première chose que la fonction

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

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!

FAQ (FAQ) sur l'auto-définition et la réécriture des fonctions JavaScript

Comment créer des fonctions dynamiquement dans JavaScript?

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

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.

Que signifie l'auto-définition des fonctions JavaScript?

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(); // 无论调用多少次,它都将保持不变
Copier après la connexion
Copier après la connexion

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.

Comment réécrire les fonctions JavaScript?

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; // 函数现在已被重定义,因此属性不存在
Copier après la connexion
Copier après la connexion

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 Quels sont les avantages et les inconvénients des fonctions JavaScript?

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.

Puis-je utiliser les fonctions Arrow pour définir et remplacer les fonctions JavaScript?

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

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!

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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal