web-dev-qa-db-fra.com

Quelle est la convention JavaScript pour aucune opération?

Quelle est la convention JavaScript pour aucune opération? Comme une commande Python pass.

  • Une option est simplement une fonction vide: function() {}
  • jQuery offre $.noop(), qui appelle simplement la fonction vide ci-dessus.
  • Est-il acceptable de simplement entrer une valeur de false ou 0?

En contexte ... tout cela fonctionne sans générer d'erreur dans Chrome:

var a = 2;
(a === 1) ? alert(1) : function() {};
(a === 1) ? alert(1) : $.noop();
(a === 1) ? alert(1) : false;
(a === 1) ? alert(1) : 0;

EDIT: Beaucoup de gens ont répondu avec "Ne faites pas ça! Modifiez la structure du code!" Cela me rappelle un post où quelqu'un a demandé comment renifler le navigateur. Il a reçu une série de messages disant: "NE FAITES PAS CELA, C'EST MAUVAIS", mais personne ne lui a dit comment renifler le navigateur . Ce n'est pas une revue de code. Imaginez que vous ayez affaire à du code hérité qui ne puisse pas être modifié, et sans aucune fonction transmise, une erreur sera renvoyée. Ou, simplement, c'est ce que le client veut, et il me paye . Alors respectueusement, s'il vous plaît répondez à la question: Quel est le meilleur moyen de spécifier une fonction "aucune opération" en JavaScript?

EDIT2: Que diriez-vous d'un de ceux-ci?

true;
false;
0;
1;
null;
99
kmiklas

Pour répondre à la question initiale, l'implémentation la plus élégante et la plus élégante d'une fonction noop en Javascript pur (comme indiqué également ici ) est Function.prototype. L'extrait ci-dessous montre son utilisation:

setTimeout(Function.prototype, 10000);

Les trois navigateurs (Chrome, Firefox et IE 11) ne font pas revenir l'interprète après 10 secondes lors de l'exécution de la procédure ci-dessus (vous pouvez tester par étape en utilisant le mode "pas à pas" dans le débogueur ).

Bien que ce soit un "vrai noop" car la plupart des navigateurs ne semblent rien faire pour exécuter le noop défini de cette manière (et donc économiser les cycles de processeur), il peut y avoir des problèmes de performances associés à cela (comme le mentionnent également d'autres dans des commentaires ou dans autres réponses).

Cependant, cela étant dit, vous pouvez facilement définir votre propre fonction noop et, en fait, de nombreuses bibliothèques et frameworks fournissent également des fonctions noop. Ci-dessous quelques exemples:

var noop = function () {};           // Define your own noop in ES3 or ES5
const noop = () => {};               // OR Define your own noop in ES6
setTimeout(noop, 10000);             // Using the predefined noop

setTimeout(function () {} , 10000);  // Using directly in ES3 or ES5
setTimeout(() => {} , 10000);        // Using directly in ES6 as Lambda (arrow function)

setTimeout(angular.noop, 10000);     // Using with angular 1.x
setTimeout(jQuery.noop, 10000);      // Using with jQuery

Voici une liste alphabétique des différentes implémentations des fonctions noop (ou des discussions connexes ou des recherches google):

Angular 1.x , Angular 2 + (Ne semble pas avoir d'implémentation native - utilisez les vôtres comme indiqué ci-dessus), Ember , jQuery , Lodash , NodeJS , Ramda , ==, React (Ne semble pas avoir d'implémentation native - utilisez la vôtre comme indiqué ci-dessus), RxJS , Souligner

BOTTOM LINE: Bien que Function.prototype soit une manière élégante d’exprimer un noop en Javascript, il peut toutefois y avoir des problèmes de performances liés à son utilisation. Ainsi, vous pouvez définir et utiliser votre propre (comme indiqué ci-dessus) ou utiliser celui défini par la bibliothèque/framework que vous pourriez utiliser dans votre code.

85
Alan C. S.

Le noop le plus concis et le plus performant est une fonction de flèche vide : ()=>{}.

Les fonctions de flèche fonctionnent de manière native dans tous les navigateurs sauf IE (il y a un transformation de babel si vous devez)): MDN


()=>{} contre. Function.Prototype

  • ()=>{} est 87% plus rapide que Function.prototype in Chrome 67.
  • ()=>{} est 25% plus rapide que Function.prototype dans Firefox 60.
  • ()=>{} est 85% plus rapide que Function.prototype dans Edge (15/06/2018).
  • ()=>{} est 65% moins de code que Function.prototype.

Le test ci-dessous chauffe avec la fonction flèche pour donner un biais à Function.prototype, mais la fonction flèche est clairement gagnante:

const noop = ()=>{};
const noopProto = Function.prototype;

function test (_noop, iterations) {
    const before = performance.now();
    for(let i = 0; i < iterations; i++) _noop();
    const after = performance.now();
    const elapsed = after - before;
    console.info(`${elapsed.toFixed(4)}MS\t${_noop.toString().replace('\n', '')}\tISNOOP? ${_noop() === undefined}`);
    return elapsed;
}

const iterations = 10000000
console.info(`noop time for ${iterations.toLocaleString()} iterations`)
const timings = {
    noop: test(noop, iterations),
    noopProto: test(noopProto, iterations)
}

const percentFaster = ((timings.noopProto - timings.noop)/timings.noopProto).toLocaleString("en-us", { style: "percent" });
console.info(`()=>{} is ${percentFaster} faster than Function.prototype in the current browser!`)
43
cchamberlain

tout ce que vous avez tendance à réaliser ici est faux. Les expressions ternaires ne doivent pas doivent être utilisées comme une déclaration complète, uniquement dans une expression, de sorte que la réponse à votre question est la suivante:

aucune de vos suggestions, faites plutôt:

var a = 2;
if (a === 1)
    alert(1)
// else do nothing!

le code est alors facilement compréhensible, lisible et aussi efficace que possible.

Pourquoi rendre cela plus difficile alors que cela peut être simple?

modifier:

Dans ce cas, une commande "no-operation" indique-t-elle fondamentalement une structure de code inférieure?

Vous manquez mon point. Tout ce qui précède concerne l'expression ternaire x ? y : z.

Toutefois, une commande no operation n'a pas de sens dans les langages de niveau supérieur tels que Javascript.

Il est généralement utilisé, dans les langages de niveau inférieur tels que Assembly ou C, pour que le processeur ne fasse rien pour une seule instruction à des fins de minutage.

Dans JS, que vous fassiez 0;, null;, function () {}; ou une instruction vide, il y a de grandes chances que l'interprète l'ignore lorsqu'il le lit, mais avant il est interprété, donc à la fin, vous ne ferez que charger votre programme plus lentement, très lentement. Nota Bene: Je suppose cela, car je ne suis impliqué dans aucun interpréteur JS largement utilisé, et il y a des chances que chaque interprète ait sa propre stratégie.

Si vous utilisez quelque chose d'un peu plus compliqué, comme $.noop() ou var foo = function () {}; foo(), alors l'interpréteur peut effectuer un appel de fonction inutile qui finira par gâcher quelques octets de votre pile de fonctions, et quelques cycles.

La seule raison pour laquelle je vois une fonction telle que $.noop() existerait, serait de pouvoir toujours attribuer une fonction de rappel à une fonction événement qui lève une exception si elle ne peut pas appeler ce rappel. Mais alors, c’est forcément une fonction que vous devez donner, et lui donner le nom noop est une bonne idée. Vous dites donc à vos lecteurs (et cela pourrait être vous dans 6 mois) que vous donnez volontairement un caractère vide. une fonction.

En fin de compte, il n’existe pas de structure de code "inférieure" ou "supérieure". Vous avez tort ou raison dans la manière dont vous utilisez vos outils. Utiliser un ternaire pour votre exemple revient à utiliser un marteau pour visser. Cela fonctionnera, mais vous n'êtes pas sûr de pouvoir accrocher quelque chose sur cette vis.

Ce qui pourrait être considéré comme "inférieur" ou "supérieur" est l'algorithme et les idées que vous mettez dans votre code. Mais c'est une autre chose.

15
zmo

Je pense que jQuery noop() est principalement destiné à empêcher le code de planter en fournissant une fonction par défaut lorsque celle demandée n'est pas disponible. Par exemple, en considérant l'exemple de code suivant, $.noop Est choisi si fakeFunction n'est pas défini, ce qui empêche le blocage du prochain appel à fn:

var fn = fakeFunction || $.noop;
fn() // no crash

Ensuite, noop() permet d'économiser de la mémoire en évitant d'écrire la même fonction vide plusieurs fois partout dans votre code. Au fait, $.noop Est un peu plus court que function(){} (6 octets enregistrés par jeton). Donc, il n'y a pas de relation entre votre code et le modèle de fonction vide. Utilisez null, false ou 0 Si vous le souhaitez, dans votre cas, il n'y aura aucun effet secondaire. En outre, il est à noter que ce code ...

true/false ? alert('boo') : function(){};

... est complètement inutile puisque vous n'appellerez jamais la fonction, et celle-ci ...

true/false ? alert('boo') : $.noop();

... est encore plus inutile puisque vous appelez une fonction vide, qui est exactement la même chose que ...

true/false ? alert('boo') : undefined;

Remplaçons l'expression ternaire par une instruction if pour voir à quel point elle est inutile:

if (true/false) {
    alert('boo');
} else {
    $.noop(); // returns undefined which goes nowhere
}

Vous pouvez simplement écrire:

if (true/false) alert('boo');

Ou même plus court:

true/false && alert('boo');

Pour répondre enfin à votre question, je suppose qu’une "opération classique sans opération" est celle qui n’est jamais écrite.

6
leaf

J'utilise:

 (0); // nop

Pour tester le temps d'exécution de cette exécution en tant que:

console.time("mark");
(0); // nop
console.timeEnd("mark");

résultat: note: 0.000ms

Utiliser Boolean( 10 > 9) peut être réduit à simplement ( 10 > 9), Ce qui retourne true. Venir avec l'idée d'utiliser un seul opérande, je m'attendais parfaitement à ce que (0); Renvoie false, mais renvoie simplement l'argument tel qu'il peut être vérifié en effectuant ce test sur la console.

> var a = (0);
< undefined
> a
< 0
3
Eggs