Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Testez vos connaissances avec un Quiz sur l'usage avancé des fonctions en JavaScript

Le , par SylvainPV

20PARTAGES

8  0 


Les fonctions sont un des éléments les plus intéressants du langage JavaScript, mais beaucoup de leurs subtilités restent méconnues. Afin de mesurer vos connaissances et de vous faire découvrir de nouvelles manières d'utiliser les fonctions, un nouveau quiz JavaScript dédié aux fonctions vient d'être publié !

Quiz: Usage avancé des fonctions

Le quiz est de niveau difficile, donc pas de panique si vous n'avez pas la moyenne Et merci de ne pas indiquer des éléments de réponse dans vos commentaires.

Pour les plus chevronnés d'entre vous, je vous propose une onzième question pas piquée des vers. Etant donné son haut niveau d'inintelligibilité, je vous laisse vous échanger des pistes de réflexion publiquement dans les commentaires de ce topic.

QUESTION BONUS
11. A votre avis, à quoi sert la fonction suivante ?
Code : Sélectionner tout
var f = Function.bind.bind(Function.call);
a) à chaîner des fonctions en gardant toujours le même contexte d'appel
b) à transformer une méthode en fonction classique où l'instance est passée en argument
c) à modifier la fonction bind pour qu'elle exécute les fonctions sur lesquelles on l'appelle
d) à faire s'arracher les cheveux aux collègues

Merci à NoSmoking, SpaceFrog et vermine pour la relecture du quiz.

Participez également à nos autres quizz :
Les quizz JavaScript.
Tous les quizz de Developpez.com dont certains portent sur le CSS, HTML ou PHP.

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de SylvainPV
Rédacteur/Modérateur https://www.developpez.com
Le 13/01/2015 à 14:05
J'ai justement changé la proposition C de la Q9 avant publication pour lever complètement le doute. Le fait qu'une variable soit dans une portée locale ne permet pas de cacher sa valeur, elles pourront toujours être retrouvées par l'utilisateur final. Ce n'est pas beaucoup plus compliqué de mettre un breakpoint que de fouiller les variables globales. Et ce n'est pas le rôle des closures de toute manière.

Pour la Q10 la réponse peut être retrouvée dans les spécifications ECMA-262.

Concernant la question bonus, Kaamo a compris le principe général. Quelqu'un a une idée de à quoi cela pourrait servir ?
1  0 
Avatar de jhenaff
Futur Membre du Club https://www.developpez.com
Le 13/01/2015 à 22:21
Ca peut servir a rendre accessibles des fonctions natives plus facilement :
var f = Function.bind.bind(Function.call);
var map = f(Array.prototype.map);

map est directement utilisable sous forme de fonction plutôt que d'appeler a chaque fois Array.prototype.map.call(.....).
Par contre je pense que c'est moins efficace côté perf (à cause du bind).
1  0 
Avatar de lysandro
Membre averti https://www.developpez.com
Le 13/01/2015 à 22:35
Je ne sais pas à quoi servent les clotures au final, je les utilise essentiellement pour émuler le mot-clef 'static' du C, en gros pour avoir des variables rémanentes, ou des fonctions, qui ne polluent pas la portée parente. Bien qu'en C, elles soient définies dans la portée d'utilisation. J'ai souvent été étonné de la confusion entre variables privées et static d'ailleurs.
1  0 
Avatar de NoSmoking
Modérateur https://www.developpez.com
Le 17/01/2015 à 10:53
pas en forme ce matin Votre score : 7 / 10 (pas terrible pour un relecteur)

Citation Envoyé par Kaamo
Mais à quoi ça peut servir à part donner un contexte d'exécution à maFonction ?
Je trouve qu'utiliser maFonction.call(context) est plus clair.
si tu n'as qu'une fois l'écriture à faire oui mais on peut étendre le raccourci à plusieurs fonctions et aller jusqu'à créer des "pseudoMACRO"
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var personne = {
  nom :    'Mac Fly',
  prenom : 'Marty'
};

var f = Function.bind.bind(Function.call);

function voirNom() {
  console.log(this.prenom +' ' +this.nom);
}
function changeNom() {
  this.nom = arguments[0] || 'unknow';
  console.log(this.prenom +' ' +this.nom);
}
// pseudo MACRO
var fct_voir   = f( voirNom);
var fct_change = f( changeNom);
on pourra donc écrire
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
// version de 'base'
voirNom.call  (personne);                 // Mac Fly
changeNom.call( personne, 'En Vacances'); // Marty En Vacances

// version 'bind.bind'
f( voirNom)( personne);
f( changeNom)( personne, 'En Vacances');

// version 'macro'
fct_voir  ( personne);
fct_change( personne, 'En Vacances');
bon d'accord il y a d'autres façon de gérer cela.
1  0 
Avatar de Lcf.vs
Membre éclairé https://www.developpez.com
Le 20/01/2015 à 21:51
Hum, mea culpa, j'ai dû mal interpréter les chiffres

Le binding est coûteux, très coûteux mais les appels sont sacrément plus performants avec ton code.

Pour ce qui est de tester l'usage de la mémoire, j'fais cela sous node

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var i,
    heap,
    cloneArray;

i = 0;
heap = process.memoryUsage().heapUsed;
cloneArray = Function.bind.bind(Function.call)(Array.prototype.slice);

for (; i < 99999; i += 1) {
    /*/
    Array.prototype.slice.call([1,2,3]); // 1170304
    /*/
    cloneArray([1,2,3]); // 688264
    //*/
}

console.log(process.memoryUsage().heapUsed - heap);
1  0 
Avatar de Kaamo
Membre émérite https://www.developpez.com
Le 12/01/2015 à 18:39
7/10, c'est mieux que mon score sur le DOM !
Sympathique ce petit test, j'aurais dû le faire demain matin après le café plutôt qu'en fin de journée, mais ma curiosité a eu le dessus

Pour la question BONUS, je dirais que c'est une sorte de wrapper qui évite de taper maFonction.call :
Code javascript : Sélectionner tout
1
2
3
4
5
function maFonction() { 
  console.log(this.nom); 
} 
  
maFonction.call({nom: 'Marty'}); // Marty
A la place, suffit donc de :
Code javascript : Sélectionner tout
1
2
var f = Function.bind.bind(Function.call); 
f(maFonction)({nom: 'Marty'});
Mais à quoi ça peut servir à part donner un contexte d'exécution à maFonction ?
Je trouve qu'utiliser maFonction.call(context) est plus clair.
0  0 
Avatar de lysandro
Membre averti https://www.developpez.com
Le 13/01/2015 à 10:07
9/10 mais la réponse à la question 9 est une réponse par défaut
@Kaamo: sans tester ?

Ah et merci, ça fait du bien
0  0 
Avatar de Kaamo
Membre émérite https://www.developpez.com
Le 13/01/2015 à 10:17
Bien oui sans tester
J'ai échoué à la 5 et à la 8 & 9 sur les closures. Parce qu'utiliser une closure, c'est cacher la valeur de certaines variables aux utilisateurs selon moi. ça ne peut pas marcher aussi comme réponse ?
0  0 
Avatar de lysandro
Membre averti https://www.developpez.com
Le 13/01/2015 à 10:45
Bravo!
La valeur d'une simple variable locale dans une fonction est aussi cachée pour l'utilisateur, non ?
0  0 
Avatar de Kaamo
Membre émérite https://www.developpez.com
Le 13/01/2015 à 11:29
Oui c'est inaccessible via le scope global.
Je trouve que la réponse 3) de la question 9 pourrait aussi bien être une bonne réponse. En définissant des variables dans une closure, on rend inaccessible leur manipulation des utilisateurs mais pas des développeurs bien sûr
0  0