43 votes

Une fonction est supérieure à celle d'un tableau?

Un de mes amis a découvert certains comportement intéressant dans du code Javascript, que j'ai décidé de poursuivre l'enquête.

La comparaison

(function (x) {return x*x;}) > [1,2,3]

les retours true dans la plupart des principaux navigateurs (Firefox, Chrome, Opera et Safari) et false dans IE9. Pour moi, il n'y a pas de résultat logique de cette comparaison autre que undefined comme il n'y a aucun moyen de dire qu'une fonction est supérieure à un tableau.

La lecture du ECMA-script standard, il est dit que les arguments de l' > lorsqu'il est utilisé sur des objets sont le résultat de l'appel de la ToNumber fonctionnement interne sur les arguments. Certains l'expérimentation et la lecture me dit que ce n'est pas le même que l'application d'un type de conversion tels que (Number) arg. La lecture de la spécification, j'ai du mal à comprendre ce qui se passe ici.

Quelqu'un peut-il me renseigner sur ce qui se passe réellement ici?

60voto

Esailija Points 74052

Dans IE<9, .toStringing (function (x) {return x*x;}) donne

"(function (x) {return x*x;})" 

Alors que dans google chrome, ça donne:

"function (x) {return x*x;}"

Si vous les comparez à:

"function (x) {return x*x;}" > "1,2,3" // true
"(function (x) {return x*x;})"  > "1,2,3"  // false

Ce qui est effectivement la même que la comparaison:

"f" > "1"
"(" > "1"

Qui est la même que la comparaison:

102 > 49
40 > 49

C'est ainsi que nous obtenons à partir d'une fonction et de la matrice de comparaison à une simple comparaison des nombres :)

54voto

T.J. Crowder Points 285826

Les opérandes > ne sont pas nécessairement converties en nombres. Le résumé relationnelle de l'algorithme de comparaison des appels ToPrimitive avec le soupçon Number, mais ToPrimitive peut toujours renvoyer une chaîne de caractères (dans le cas de ces deux fonctions et tableaux, il n').

Donc, vous vous retrouvez la comparaison de deux chaînes de caractères. Le résultat de l'appel d' toString sur les objets de fonction n'est pas définie par la spécification, bien que la plupart des grands moteurs de retourner le code source de la fonction (ou la forme de certains, et la mise en forme varie). Le résultat de l'appel d' toString sur les tableaux est le même que join.

Donc, les chances sont que vous finirez essentiellement faire ceci:

"function (x) {return x*x;}" > "1,2,3"

Depuis, la forme exacte de la chaîne de la fonction peut varier d'un navigateur à navigateur (et note Esailija enquêtes — ressemble à IE9 conserve l'extérieur (), Chrome ne fait pas), il n'est pas trop surprenant que le résultat peut varier.

5voto

Jivings Points 10892

Plongeons-nous dans la Spécification ECMA. J'ai inclus les numéros de section de sorte que vous pouvez de référence.

11.8.2 L'Opérateur Supérieur à ( > )

La production RelationalExpression : RelationalExpression > ShiftExpression est évaluée de la façon suivante:

  1. Laissez lref être le résultat de l'évaluation RelationalExpression.
  2. Laissez lval être GetValue(lref).
  3. Laissez rref être le résultat de l'évaluation ShiftExpression.
  4. Laissez rval être GetValue(rref) .
  5. Soit r la suite de l'exécution de l'abstrait relationnel comparaison rval < lval avec LeftFirst égale à false. (voir 11.8.5).

L'important c'est de l' Abstrait Relationnel Comparaison. Ce qui est défini:

11.8.5 L'Abstrait Relationnelle De L'Algorithme De Comparaison

L' toPrimitive fonction sera la première à être appelée sur les Objets. Bien que ce est biaisé à la Nombre de retours si cela est possible, les Chaînes peuvent aussi être dérivées. Une fois que cela s'est produit, les éléments suivants seront examinés:

un. Si py est un préfixe de px, retourne false. (Une Chaîne de valeur p est un préfixe de la Chaîne de valeur de q, si q peut être le résultat de la concaténation p et une autre Chaîne. r. Notez que tout La chaîne est un préfixe de lui-même, parce que r peut être la Chaîne vide.)

b. Si px est un préfixe de py, retourner la valeur true.

c. Soit k le plus petit entier positif tel que le caractère à la position k dans px est différent du caractère à la position k dans les py. (Il doit y avoir un tel k, ni de Chaîne est un préfixe de l'autre).

d. Soit m un entier qui est le code de l'unité de valeur pour le caractère à la position k dans les px. e. Soit n le nombre entier qui est le code de l'unité de valeur pour le caractère à la position k dans les py. f. Si m < n, renvoie la valeur true. Sinon, retourne false.

Cela signifie que le premier caractère de la Chaîne qui est différent de l'autre, seront examinés. Comme il a été souligné par les Esailija, c'est à dire de l' toString() fonction retourne un peu différente de la Chaîne pour que les autres navigateurs, résultant en une autre comparaison de prendre place.

Cette différence entre les navigateurs qui semble être valide comme il est indiqué ici:

15.2.4.4 Objet.le prototype.valueOf ( )

Lorsque le valueOf méthode est appelée, les mesures suivantes sont prises:

  1. Laissez-O être le résultat de l'appel ToObject en passant la valeur de l'argument.
  2. Si O est le résultat de l'appel au constructeur de l'Objet avec un objet hôte (15.2.2.1), puis un. Retour O ou une autre valeur, par exemple l'hôte de l'objet à l'origine transmis au constructeur. Le spécifique résultat renvoyé est mise en œuvre définies.
  3. Retour O.

2voto

Mike Christensen Points 29735

IE et les autres navigateurs utilisent la même chaîne de comparaison pour les deux objets. La raison de cette différence est IE va convertir la fonction dans la chaîne de caractères saisie:

(function (x) {return x*x;})

Les autres navigateurs (tester sur Firefox) sortira sa propre compilé interprétation de la fonction:

function (x) {
    return x * x;
}

Depuis le premier caractère de l'IE de la fonction de représentation est - (, ce qui est supérieur à 1, il sera de retour faux. Depuis f est inférieur 1, les autres navigateurs retournera true.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X