14 commentaires

  • Nathan dit :

    C’est… tout à fait normal ? Dans n’importe quel langage même…?

    le premier c’est un for de 0 à longueur donc c’est un nombre
    le deuxième c’est un foreach sur les clés d’un tableau donc c’est un nombre aussi
    le troisième c’est un foreach sur les valeurs d’un tableau donc c’est un string car il contient des strings

  • Philippe dit :

    Rien de choquant.
    C’est un tableau dans les deux premiers cas, et «i» en est l’indice.
    Dans le troisième cas, «t» devient une collection, et i un membre.

  • Guildem dit :

    Bah oui, tout comme Philippe, je ne suis pas vraiment choqué, un entier incrémenté dans le premier cas, une liste de clés (numériques, vu que c’est un tableau) dans le second, et une collection de chaines dans le 3ème.

    Javascript ne gère pas les quotes simples comme un type “char”, mais comme un “string” au même titre qu’un quote double. C’est le cas pour de nombreux langages de scripts (PHP aussi par exemple).

  • Pouet78 dit :

    Pour la 3eme, i ne représenterai pas la valeur plutôt que l’indice? Je ne connais pas bien JS mais c’est ce que j’attendrai.

  • bunam dit :

    https://codepen.io/bunam/pen/yQpQW
    i contient a chaque fois des indices

  • Guildem dit :

    Bah oui, tout comme Philippe, je ne suis pas vraiment choqué, un entier incrémenté dans le premier cas, une liste de clés (numériques, vu que c’est un tableau) dans le second, et la collection de caractères dans le 3ème.

    Javascript ne gère pas les quotes simples comme un type “char”, mais comme un “string” au même titre qu’un quote double. C’est le cas pour de nombreux langages de scripts (PHP aussi par exemple).

  • Philippe dit :

    J’ai écrit une bêtise.
    Dans le troisième cas «i» est la propriété (“1”, “2”, “3”) pas la valeur.

  • TheGuit dit :

    Tout a fait normal. C’est juste que dans d’autres langage le for..in aurait fail.

    for..in travail sur des objets. Le tableau est dans ce cas là converti en objet. Les propriété d’un objet son textuel.

    Essayé de faire :
    let a = {}
    a.5 = “test”

    ça ne marche pas
    a[‘5’] = “test”

    Ça marche.

    Donc les exemples sont tout a fait logique et normal.

  • Fred dit :

    Merci Philippe, un nouveau mystère du Javascript s’éclaircit 😀 .
    Non sérieux, je passe mon temps à dire de pas utiliser les for..in sur des tableaux parce qu’on est très restrictif sur les typages et que ia toujours un truc qui foire qqpart et ils persistent à mettre des parseInt() derrière xD .

  • Luc dit :

    Dans mon dessin, j’aurais du ajouter le “for(let v of t)” pour faire la distinction avec “for(let i in t)”… 🙂

  • Bruno Lesieur dit :

    Très drôle ! C’est effectivement ce que je constate également !

    Pour être un peu plus critique.

    #faits

    Seul le premier type de boucle garanti que `i` soit de type `number` puisque nous décidons nous même d’en faire un tel type (`let i = 0`, puis `i++`).

    Rien ne nous empêcherait, par exemple, d’en faire un type `string` à chaque itération.

    Ainsi `i` dans l’exemple
    “`
    let t = [‘h’, ‘o’, ‘p’];
    for (let i = ‘0’; i < t.length; i = +i + 1 + '') {
    console.log(i);
    console.log(typeof i);
    }
    “`
    Sera de type `string`.

    En ce qui concerne l'opérateur `for … of`, l'exemple est fallacieux puisqu'en réalité `i` n'est pas censé représenter nécessairement un nombre, mais l'objet qui se trouve dans le tableau.

    Aussi l'exemple suivant
    “`
    var t = ['h', 'o', 'p'];
    for (var i of t) {
    console.log(i);
    console.log(typeof i);
    }
    “`
    retournera des types `string` (et pas `number` comme l'utilisation de `t.keys()`.

    Donc naturellement, l'exemple suivant :
    “`
    var t = [true, false, true];
    for (var i of t) {
    console.log(i);
    console.log(typeof i);
    }
    “`
    retournera pour `i` un type `boolean`.

    Le fait qu'avec l'utilisation de `.keys()` la valeur soit un `number` n'est donc pas de notre ressors mais de celui de cette fonction (qui retourne l'indice qui est un `number`).

    Pour finir, l'opérateur `for … in` semble, lui, affecter à `i` une `string` (ce qui effectivement n'est pas la même chose que l'utilisation de `for` ou de `for … of`). Je me serai également attendu à ce qu'il affecte un `number` comme ça sans trop y réfléchir mais il n'y a rien d’étonnant non plus : `for … in` n'est pas réservé aux `Array` mais peut également fonctionner avec des `Object`. Et les indices des objets ne sont pas nécessairement des nombres. Regardez l'exemple suivant :

    “`
    let v = {
    'str1': 'h',
    'str2': 'o',
    'str3': 'p',
    };

    for (var i in v) {
    console.log(i);
    console.log(typeof i);
    }
    “`

    logique que ça retourne un type `string`.

    Regardez également l'exemple suivant

    “`
    const symbol1 = Symbol('h');
    const symbol2 = Symbol('o');
    const symbol3 = Symbol('p');

    let t = {
    symbol1: 'h',
    symbol2: 'o',
    symbol3: 'p',
    };

    for (var i in t) {
    console.log(i);
    console.log(typeof i);
    }
    “`

    Pas d'autre choix que d'utiliser `.toString()` pour « représenter » le `Symbol`.

    Il n'est pas illogique que le système nous retourne une string (`symbol1`, `symbol2` et `symbol3`). Puisque `for … in` doit être en mesure de retourner différent type de valeur.
    Il a été décidé « arbitrairement » que le système les retournes en utilisant la valeur `toString()` (ce qui est quand même pratique pour les `string` ou les `Symbol`.

    ======

    #opinion

    Bref, c'est bien marrant à première vu, mais il n'y a rien qui me choque nécessairement. Faire le choix de la `string` pour conserver une cohérence entre les Symbol (qui n'étaient pas accessible par le passé mais qui existaient bien dans le système) et tout autre type plutôt que dans le cas spécifique ou l'indice est convertissable en `number`, le forcer dans le système pour garder une cohérence entre `for` et `for … in` est quelque chose « d'arbitraire ».

    Si vous êtes sur que votre indice sera de type `number`, vous pouvez tout simplement convertir la valeur en `number` avec l'opérateur `+` si cela est réellement nécessaire.

    “`
    var t = ['h', 'o', 'p'];
    for (var i in t) {
    console.log(+i);
    console.log(typeof +i);
    }
    “`

    Et oui, « si l'objet est de type `Array` alors faire que `for … in` retourne un `number` plutôt qu'une `string` était quelque chose que arbitrairement nous aurions pu faire : pour preuve, cette image le montre. Mais ce n'était pas nécessairement plus « logique » que l'état actuelle en fonction du point de vu adopté.

    Maintenant, au delà de ça, l'argument « j'aime pas le JavaScript » est un argument valide (et une opinion) pour justifier le fait de jeter son PC dans les chiottes (même si la finalité me semble un peu excessive :D).

    Pas besoin d'homme de paille donc !

  • Sylvain dit :

    Il y a plus simple/concret pour se moquer du typage de JS, par exemple: https://www.destroyallsoftware.com/talks/wat 😉

  • Alex dit :

    Je crois que Array(16).join(“wat” – 1) + ” Batman !” est mon favori de la vidéo.

Un truc à dire ?