JavaScript Clone Array

#17722

(je_rale_contre_JS pour la 25436e fois)

Comment dupliquer un tableau en JS.

Ça ?

var new_table = old_table

Nope, car si on modifie old_table, alors le new_table s’en trouvera également modifié : ce n’est pas une duplication de la variable mais une référence à l’ancien tableau : c’est comme si les mêmes données sont accessibles sous deux noms.

Pour dupliquer un tableau à une seule dimension, il faut faire :

for (var i in table) {
    new_table[i] = table[i];
}

Mais si le tableau est un tableau d’objets, ou même un objet d’objets (donc de plus d’une dimension) ?
Ben la méthode précedente ne marche pas : si table[i] contient un objet, alors cet objet sera rendu accessible dans new_table[i], mais sans y être copié !

Modifier table[i] changera donc également new_table[i].

La seule méthode que j’ai trouvé (dans le lien) qui tienne en une ligne c’est ça :

var clone = JSON.parse( JSON.stringify( myArray ) );

On prend le tableau, on le transforme en une représentation textuelle JSON (à ce stade c’est juste du texte, sans objets, références, indexes…) puis on le retransforme entièrement en tableau. Là il sera dupliqué totalement, même si le tableau fait 15 dimensions.

C’est farfelu, oui.

https://davidwalsh.name/javascript-clone-array

for...of - JavaScript | MDN

#17719

Si je comprends bien, en JS, la différence entre for..in et for..of c’est un comme la différence entre foreach ($table => $element) et foreach ($table as $element) du PHP.

L’un place dans $element la clé, et l’autre la valeur.
En PHP, on peut même faire $table => $key as $value, où l’on obtient la clé et la valeur en même temps.

Sauf qu’en JS, on a aussi le for, forEach, .each(), et bien d’autres trucs…

Note : optimiser les boucles en programmation

#17705

J’ai décidé d’implémenter ça : https://sciencetonnante.wordpress.com/2015/11/06/la-machine-a-inventer-des-mots-version-ikea/ en javascript (pour un faire un petit générateur de mots dans une page web).

Y a une chose sur laquelle je reviens, et c’est pas la première fois, et ça semble trivial, mais ça change tout.

Dans ce script, en gros, j’ai 80 000 mots et je chercher les occurrences de triplets de lettres là-dedans. Donc en fait, j’ai 3 boucles imbriquées (de A à Z) sur chacun des 80 000 mots.

Question tout con : quel est le plus rapide,
– boucler sur les mots, puis sur les lettres ?
Comme ça :

for (w in words) {
    for (i in alphabet) {
        for (j in alphabet) {
            for (k in alphabet) {
                check(ijk, w)
            }
        }
    }
}

– boucler sur les lettres puis les mots ?
Comme ceci :

for (i in alphabet) {
    for (j in alphabet) {
        for (k in alphabet) {
            for (w in words) {
                check(ijk, w)
            }
        }
    }
}

Mathématiquement, dans les deux cas, on fait 80 000 × 26³ = 1,4 milliards de boucles.

Pourtant, avec une toute petite astuce, on peut rendre le premier code beaucoup plus rapide.
L’idée est qu’il y a 26 lettres dans l’alphabet. Mais les mots font rarement 26 lettres, et quand ils le font, c’est rarement avec toutes les lettres.

On va donc, à chaque boucle, commencer par vérifier si la lettre sur laquelle on est est contenue dans le mot.
Si il n’y est pas, c’est inutile de faire les deux autre boucles internes : la suite contenant la première lettre n’y sera pas non plus. Dans ce cas, on économise 26² boucles pour ce mot :

for (w in words) {
    for (i in alphabet) {
        if (check(i, w)) {
            for (j in alphabet) {
                if (check(ij, w)) {
                    for (k in alphabet) {
                        check(ijk, w)
                    }
                }
            }
        }
    }
}

Sachant que les mots font autour de ~8 lettres, ça représente (26-8)×26² = 12 168 boucles par mot !

Du coup, au lieu de 1,4 milliards de boucles, on réduit ça directement à 432 millions.
Ensuite, on économise encore sur le test de la chaîne "ij" (si la seconde lettre "j" ne se trouve pas dans le mot, alors on économise 26 boucles par mot : on passe en dessous des 400 millions.

La différence est grande : on a divisé le temps par 3~4 juste avec ça.
Et ça c’est juste une estimation grossière : en français, les mots — surtout les longs — ont plutôt des lettres en doubles que seulement des lettres différentes.

En pratique, je passe d’un temps d’éxécution de ~2 minutes à seulement 3 secondes… J’ai divisé le temps par 40.

Tout ceci est tout bête, tout con, mais pensez-y : parfois une ligne de code en plus, un simple "if" juste avant une fonction lourde peut tout changer.
Ok, fait un test « if » c’est une condition en plus et donc un calcul en plus. Mais si ça permet d’économiser sur une fonction qui prend 40 fois plus de temps… Alors ça en vaut la même. En l’occurrence, si ma fonction prend vraiment 40 fois plus de temps qu’un "if", alors je serait gagnant dès qu’on mot fait moins de 25 lettres différentes, ce qui est toujours le cas en français.

%%

Autre exemple dans mon code : pour faire le teste de présence d’un triple de lettres consécutifs dans un mot, j’utilisais les regex. C’est lourd et lent.
À la place, j’ai opté pour une fonction avec un simple "str.indexOf()", qui regarde si une souschaîne est contenue dans une chaîne. C’est bien plus rapide qu’un regex. Là, le temps a été divisé par un facteur 100 environ.

Sur une page normale, j’imagine qu’on n’aurait gagné que des micro-secondes. Mais quand on boucle 26³ fois sur chacun de 80 000 mots, le gain de temps est monstre.

Why You Shouldn't Use A Web Framework - DEV Community 👩‍💻👨‍💻

#17630

It's easier for beginners to use a framework

Sure, if you're a Sith.

Déjà que JS lui même vient, de base dans les navigateurs, avec une panoplie énorme de fonctionnalités, donc les 3/4 ne seront jamais utilisés dans quelque programme que ce soit, alors ajoute une sur-couche pour reformuler toutes ces fonctions de façon différente, à quoi bon ?

https://dev.to/gypsydave5/why-you-shouldnt-use-a-web-framework-3g24

What’s wrong with CSS-in-JS? | Brad Frost

#17373

J'ai jamais été fan du full-CSS-in-JS, et je rejoins ce que disait Daniel Glazman ici : les arguments généralement invoqués pour dire "non au CSS" ne tiennent juste pas debout et tendent même plutôt à démontrer que CSS a de bon nombre de points communs avec des langages de programmation !

Le mieux quand on vient se greffer sur un projet déjà existant c'est évidement de respecter la structure de l'existant, mais s'il est nécessaire de tout recommencer ou de créer un truc nouveau, je préfère utiliser les différentes techno pour ce qu'elles ont été prévues :

- HTML pour le code source de la page et le contenu
- CSS pour la décoration
- JS pour l'interaction et l'interface .

On peut utiliser JS pour modifier le CSS ou le HTML, mais généralement c'est à éviter.
Quand il faut modifier ce qui s'affiche à l'écran, je ne touche pas aux éléments HTML : je fais switcher des classes et je laisse le CSS faire le reste.

Ça me semble être la solution la plus propre : sans CSS le HTML s'affiche et le contenu est visible, et sans JS aussi, donc le contenu reste accessible. Ce n'est pas toujours la solution la plus légère par contre...

Ultra-light JS/CSS image slider

#17232

Hop, à nouveau tous les scripts / lib de sliders que je trouve sont trop lourds, trop complets, demandent jQuery…

… du coup j’ai pondu un slider très simple en quelques lignes de JS & CSS.

Rien de complexe, mais c’est ultra-léger, sans dépendances, et ça marche.
Et c’est assez simple à comprendre pour que vous puissiez ajouter ce que vous voulez vous-même :).

javascript - Can (a ==1 && a== 2 && a==3) ever evaluate to true? - Stack Overflow

#17169

:o

Effectivement, les espaces avant et après les variables sont étrangement posées. Si les espaces sont des espaces « exotiques » en unicode, ils font partie du nom de la variable et on a donc trois variables différentes :

a␣ = 1, ␣2 = 3, a = 3;
if (a␣ == 1 && a == 2 && a == 3) {
  console.log('Hello World!');
}

Mais même avec ça, il y a une solution relativement simpliste : suffit de redéclarer il suffit de savoir le fonctionnement même de JavaScript, qui essaye toujours de trouver l’égalité sur les types de variables, puis de redéfinir une méthode qui existe déjà :

const a = {
  i: 1,
  toString: function () {
    return a.i++;
  }
}

if (a == 1 && a == 2 && a == 3) {
  console.log('Hello World!');
}

https://stackoverflow.com/questions/48270127/can-a-1-a-2-a-3-ever-evaluate-to-true

Tous les parsers JSON sont mauvais - LinuxFr.org

#16944

Nan, c’est juste qu’ils ne permettent pas d’analyser des objets qui ont un trop grand nombre de niveaux d’imbrications. Le parseur en lui-même n’a aucun problème (je ne vois pas ça comme un soucis du parseur à proprement parler, c’est à dire le code qui va lire le JSON en entrée, bit par bit, et déclencher les fonctions qu’il faut au bon moment).

Selon l’article, Ruby plante à partir de 100 imbrications. C++ à 13 786.

C’est gênant, mais il faut bien une limite quelque part :/.

Il ne m’est jamais arrivé d’atteindre la limite sur le parsage du JSON. Par contre, j’ai déjà poussé à bout le moteur SQLite en PDO (qui a une limite de 1000 pour le nombre de variables que l’on peut mettre dans le prepare()).
Il me suffit alors de faire plusieurs requêtes plus petites au lieu d’un énorme.

AMP, and why I don't like it | nota-bene.org

#16935

Perso je vois pas tellement l’intérêt.

Il est assez simple de faire des pages web légères et rapides sans utiliser de framework / API / site externe.

Si tout le monde virait déjà tous les scripts qui apportent que-dalle à leur page, le web serait déjà beaucoup plus rapide !

Et je ne parle pas de la pub (pas forcément, en fait), mais juste des trucs comme les scripts de tracking, les scripts de popup, les scripts de rézosocio (alors qu’un lien HTML suffit pour partager un article)…
Tout ça ne n’apporte rien à l’utilisateur, c’est juste là pour l’égo du blogueur. Si vous voulez des stats, regardez les logs du serveur, tout simplement.

C’est pas comme si je demandais non plus de faire un site sans JS du tout, ni un site ultra-sofistiqué qui doit absolument fonctionner sur un 3310, mais simplement de revenir un peu aux bases.

Un seul exemple : https://lehollandaisvolant.net/tout/tools/graph/
j’avais pris cette idée d’une autre page. Cette page avait utilisé jQuery juste pour prendre le contenu placé dans le champ et la transmettre au code qui fait fonctionner le graphique. C’était d’une lenteur abominable.
Rien que virer jQuery donne le résultat visible ici. Et j’ai eu exactement le même problème avec une version de cet outil qui devra tracer des graphiques en 3D.

J’aime bien faire du vanilla-JS (javascript tout seul, sans framework superflu), tout simplement parce qu’on peut déjà tout faire et c’est guerre plus long à faire, et c’est carrément plus rapide.
Et franchement, à quoi bon inclure toute une lib externe de 100 ko si c’est juste pour traiter un event sur un seul bouton ? C’est ridicule.

C'est pourtant ce genre de choses qui ralentissent le web.

C’est pas compliqué de faire des trucs simples en pure-JS :
détecter le sens du scroll ? 10 lignes de JS.
créer un sommaire pour une page web ? 40 lignes.
un lazyload ? 10 lignes de JS aussi

Ou même des trucs sans JS du tout :
un champ / formulaire flexible ? quelques lignes de CSS