web-dev-qa-db-fra.com

Correction des fonctions de la matrice JavaScript dans Internet Explorer (indexOf, forEach, etc.)

Comme détaillé ailleurs , et apparemment apparemment bien connu, Internet Explorer (version 7 et, dans certains cas, version 8) n’implémente pas les fonctions de clé, en particulier sur Array (telles comme forEach, indexOf, etc.).

Il existe un certain nombre de solutions de contournement ici et là, mais je souhaiterais incorporer un ensemble approprié d'implémentations canoniques dans notre site plutôt que de copier-coller ou de modifier nos propres implémentations. J'ai trouvé js-methods , qui semble prometteur, mais je pensais poster ici pour voir si une autre bibliothèque est plus fortement recommandée. Quelques critères divers:

  • La bibliothèque doit simplement être une opération inexistante pour les fonctions pour lesquelles un navigateur a déjà des implémentations pour (js-methods semble faire très bien ici).
  • Non - GPL , s'il vous plaît, cependant LGPL est acceptable.
137
cemerick

Beaucoup utilisent les implémentations de secours MDC (par exemple, pour indexOf ). Ils sont généralement rigoureusement conformes aux normes, même au point de vérifier explicitement les types de tous les arguments.

Malheureusement, s'il est clair que les auteurs considèrent ce code comme trivial et librement utilisable, il ne semble pas exister de concession de licence explicite pour l'écrire. Le wiki dans son ensemble est CC Attribution-ShareAlike, s'il s'agit d'une licence acceptable (bien que CC ne soit pas conçu pour le code en tant que tel).

js-method semble bien en général, mais n'est pas conforme aux normes en ce qui concerne la manière dont les fonctions sont supposées être (par exemple, des éléments de liste non définis, des fonctions qui modifient la liste). Il regorge également d'autres méthodes aléatoires non standard, y compris des méthodes discutables telles que les dodgy stripTags et le codec UTF-8 incomplet (ce qui est également un peu inutile compte tenu de l'astuce unescape(encodeURIComponent)).

Pour ce que cela vaut, voici ce que j'utilise (que je publie par la présente dans le domaine public, si on peut dire qu'il est protégé par le droit d'auteur). Il est un peu plus court que les versions de MDC, car il ne tente pas de saisir le caractère que vous n'avez pas fait quelque chose de stupide comme passer des rappels sans fonction ou des index non entiers, mais en dehors de cela, il essaie d'être conforme aux normes. (Faites-moi savoir si j'ai manqué quelque chose; ;-))

'use strict';

// Add ECMA262-5 method binding if not supported natively
//
if (!('bind' in Function.prototype)) {
    Function.prototype.bind= function(owner) {
        var that= this;
        if (arguments.length<=1) {
            return function() {
                return that.apply(owner, arguments);
            };
        } else {
            var args= Array.prototype.slice.call(arguments, 1);
            return function() {
                return that.apply(owner, arguments.length===0? args : args.concat(Array.prototype.slice.call(arguments)));
            };
        }
    };
}

// Add ECMA262-5 string trim if not supported natively
//
if (!('trim' in String.prototype)) {
    String.prototype.trim= function() {
        return this.replace(/^\s+/, '').replace(/\s+$/, '');
    };
}

// Add ECMA262-5 Array methods if not supported natively
//
if (!('indexOf' in Array.prototype)) {
    Array.prototype.indexOf= function(find, i /*opt*/) {
        if (i===undefined) i= 0;
        if (i<0) i+= this.length;
        if (i<0) i= 0;
        for (var n= this.length; i<n; i++)
            if (i in this && this[i]===find)
                return i;
        return -1;
    };
}
if (!('lastIndexOf' in Array.prototype)) {
    Array.prototype.lastIndexOf= function(find, i /*opt*/) {
        if (i===undefined) i= this.length-1;
        if (i<0) i+= this.length;
        if (i>this.length-1) i= this.length-1;
        for (i++; i-->0;) /* i++ because from-argument is sadly inclusive */
            if (i in this && this[i]===find)
                return i;
        return -1;
    };
}
if (!('forEach' in Array.prototype)) {
    Array.prototype.forEach= function(action, that /*opt*/) {
        for (var i= 0, n= this.length; i<n; i++)
            if (i in this)
                action.call(that, this[i], i, this);
    };
}
if (!('map' in Array.prototype)) {
    Array.prototype.map= function(mapper, that /*opt*/) {
        var other= new Array(this.length);
        for (var i= 0, n= this.length; i<n; i++)
            if (i in this)
                other[i]= mapper.call(that, this[i], i, this);
        return other;
    };
}
if (!('filter' in Array.prototype)) {
    Array.prototype.filter= function(filter, that /*opt*/) {
        var other= [], v;
        for (var i=0, n= this.length; i<n; i++)
            if (i in this && filter.call(that, v= this[i], i, this))
                other.Push(v);
        return other;
    };
}
if (!('every' in Array.prototype)) {
    Array.prototype.every= function(tester, that /*opt*/) {
        for (var i= 0, n= this.length; i<n; i++)
            if (i in this && !tester.call(that, this[i], i, this))
                return false;
        return true;
    };
}
if (!('some' in Array.prototype)) {
    Array.prototype.some= function(tester, that /*opt*/) {
        for (var i= 0, n= this.length; i<n; i++)
            if (i in this && tester.call(that, this[i], i, this))
                return true;
        return false;
    };
}

D'autres méthodes ECMA262-5 non implémentées ici incluent Array reduce/reduceRight, les méthodes JSON et les quelques nouvelles méthodes Object pouvant être implémentées de manière fiable en tant que fonctions JS.

219
bobince

Jetez un oeil à nderscore.js .

27
rfunduk

Kris Kowal a compilé une petite bibliothèque qui sert de relais pour les fonctions ECMAScript 5 susceptibles de ne pas figurer dans l'implémentation du navigateur. Certaines fonctions ont été révisées à maintes reprises par d’autres personnes afin d’être optimisées pour la vitesse et de contourner les bugs du navigateur. Les fonctions sont écrites pour suivre la spécification aussi étroitement que possible.

es5-shim.js a été publié sous la licence MIT), les extensions Array.prototype sont presque au sommet et vous pouvez couper et supprimer toutes les fonctions dont vous n'avez pas besoin. Je vous suggère également de minifier le script car les commentaires le rendent beaucoup plus volumineux que nécessaire.

9
Andy E

Ces scripts ne fonctionnent pas bien dans mes tests. Je crée un fichier avec les mêmes fonctions basées sur MDN des documents.

Trop de problèmes sont résolus dans Internet Explorer 8. Voir le code dans egermano/ie-fix.js.

1
egermano

Par "ne pas implémenter de fonctions clés", vous voulez dire en réalité "conforme à l'ECMA 262 3ème éd", n'est-ce pas? :)

Les méthodes que vous mentionnez font partie de la nouvelle 5ème édition - pour les navigateurs ne la prenant pas en charge, vous pouvez utiliser le 'shim' suivant qui s'étend du 3ème au 5ème http://github.com/ kriskowal/narwhal-lib/blob/narwhal-lib/lib/global-es5.js .

1
Sean Kinsey

Avec le Underscore.js

var arr=['a','a1','b'] _.filter(arr, function(a){ return a.indexOf('a') > -1; })

0
sri_bb