Internet Explorer tarayıcıları için JavaScript'te Array indexOf () nasıl düzeltilir


295

Herhangi bir uzunlukta JavaScript ile çalıştıysanız, Internet Explorer'ın Array.prototype.indexOf () [Internet Explorer 8 dahil] için ECMAScript işlevini uygulamadığını bilirsiniz. Çok büyük bir sorun değil, çünkü sayfanızdaki işlevselliği aşağıdaki kodla genişletebilirsiniz.

Array.prototype.indexOf = function(obj, start) {
     for (var i = (start || 0), j = this.length; i < j; i++) {
         if (this[i] === obj) { return i; }
     }
     return -1;
}

Bunu ne zaman uygulamalıyım?

Prototip işlevinin var olup olmadığını kontrol eden ve yoksa Array prototipini genişleten aşağıdaki kontrolle tüm sayfalarıma sarmalıyım?

if (!Array.prototype.indexOf) {

    // Implement function here

}

Veya tarayıcı kontrol ve Internet Explorer olup olmadığını sadece uygulamak?

//Pseudo-code

if (browser == IE Style Browser) {

     // Implement function here

}

Aslında Array.prototype.indexOfECMA-262 / ECMAScript'in bir parçası değildir. Bkz. Ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf Belki düşünüyorsunuz String.prototype.indexOf...
Crescent Fresh

5
Orijinal standardın bir parçası değil, bir uzantıdır. Bununla birlikte, Javascript 1.6'nın (
IE'nin

1
@Josh: sadece "IE ECMAScript işlevini uygulamaz ..." atıfta bulundu
Crescent Fresh

4
Uygulamanızı Array.indexOfolumsuz başlangıç ​​endeksleri dikkate almaz. Mozilla'nın öneri durdurma boşluğu uygulamasına buradan bakın: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
nickf

3
Soruyu "===" kullanmak üzere güncelledim, çünkü insanların "==" ile kopyalayacağından endişeleniyorum ve bu yanlış olur - bunun dışında. Eli Grey'in cevabına bakın.
joshcomley

Yanıtlar:


213

Böyle yap ...

if (!Array.prototype.indexOf) {

}

As MDC tarafından uyumluluk tavsiye .

Genel olarak, tarayıcı algılama kodu büyük bir hayır-hayır.


Soruyu düzenlemek için yeterli temsilcim yok ama ECMAScript lingo'yu kaldırmak ve uygun ifadelerle değiştirmekten çekinmeyin. Tekrar teşekkürler
Bobby Borszich

12
Bu tür bir algılama kullanıyorsanız dikkatli olun. Başka bir kütüphane, test etmeden önce bu işlevi uygulayabilir ve standartlara uygun olmayabilir (prototip bir süre önce yaptı). Düşmanca bir ortamda çalışsaydım (çok sayıda farklı kütüphane kullanan birçok kodlayıcı), bunlardan hiçbirine güvenmezdim ...
Pablo Cabrera

"Bağlantılı" sütun ---> gerçekten kullanışlıdır! Burada cevabı seviyorum: stackoverflow.com/questions/1744310/…
gordon

Her js dosyasına sarılması gerekiyor mu?
rd22

MDC tam olarak kimdir?
Ferrybig

141

Alternatif olarak, tarayıcılarda çalışması gereken jQuery 1.2 inArray işlevini kullanabilirsiniz :

jQuery.inArray( value, array [, fromIndex ] )

'İndexOf' yerel koddur (sağda), bu nedenle jQuery 'inArray ()', mümkün olduğunda yerel kullanım ve olmadığında çoklu dolgu gibi hızlı olur mu?
Jeach

10
Kendi yorumuma cevap vermek için ok (yukarıda), sadece uyguladım ve Chrome'da 'indexOf ()' kullandığım kadar hızlı, ama IE 8'de çok, çok yavaş ... yani en azından biliyoruz 'inArray ()' mümkün olduğunda yerel kullanır.
Jeach

78

Tam kod daha sonra bu olurdu:

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(obj, start) {
         for (var i = (start || 0), j = this.length; i < j; i++) {
             if (this[i] === obj) { return i; }
         }
         return -1;
    }
}

Bunun yanı sıra diğer dizi işlevlerine gerçekten kapsamlı bir cevap ve kod için Yığın Taşması sorusunu inceleyin Internet Explorer'da JavaScript Dizisi işlevlerini düzeltme (indexOf, forEach, vb.) .


2
sadece tam şeye sahip olduğunuz için teşekkür ederim. Yeni bir projede platformlar arası indexOf'a ihtiyaç duyduğumda bu sayfayı sık sık ziyaret ediyorum ve snippet'iniz tam kodu olan tek kişidir. :) Bir kaç kişi bu sayfayı sık sık toplar.
dylnmc


10

Kullanılarak tanımlanıp tanımlanmadığını kontrol etmelisiniz if (!Array.prototype.indexOf).

Ayrıca, uygulamanız indexOfdoğru değil. Sen kullanmalısınız ===yerine ==sizin içinde if (this[i] == obj)aksi takdirde açıklamada [4,"5"].indexOf(5)yanlıştır sizin uygulanmasına göre 1 olacaktır.

MDC'deki uygulamayı kullanmanızı öneririm .


9

Mozilla resmi çözümü var: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf

(function() {
    /**Array*/
    // Production steps of ECMA-262, Edition 5, 15.4.4.14
    // Reference: http://es5.github.io/#x15.4.4.14
    if (!Array.prototype.indexOf) {
        Array.prototype.indexOf = function(searchElement, fromIndex) {
            var k;
            // 1. Let O be the result of calling ToObject passing
            //    the this value as the argument.
            if (null === this || undefined === this) {
                throw new TypeError('"this" is null or not defined');
            }
            var O = Object(this);
            // 2. Let lenValue be the result of calling the Get
            //    internal method of O with the argument "length".
            // 3. Let len be ToUint32(lenValue).
            var len = O.length >>> 0;
            // 4. If len is 0, return -1.
            if (len === 0) {
                return -1;
            }
            // 5. If argument fromIndex was passed let n be
            //    ToInteger(fromIndex); else let n be 0.
            var n = +fromIndex || 0;
            if (Math.abs(n) === Infinity) {
                n = 0;
            }
            // 6. If n >= len, return -1.
            if (n >= len) {
                return -1;
            }
            // 7. If n >= 0, then Let k be n.
            // 8. Else, n<0, Let k be len - abs(n).
            //    If k is less than 0, then let k be 0.
            k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
            // 9. Repeat, while k < len
            while (k < len) {
                // a. Let Pk be ToString(k).
                //   This is implicit for LHS operands of the in operator
                // b. Let kPresent be the result of calling the
                //    HasProperty internal method of O with argument Pk.
                //   This step can be combined with c
                // c. If kPresent is true, then
                //    i.  Let elementK be the result of calling the Get
                //        internal method of O with the argument ToString(k).
                //   ii.  Let same be the result of applying the
                //        Strict Equality Comparison Algorithm to
                //        searchElement and elementK.
                //  iii.  If same is true, return k.
                if (k in O && O[k] === searchElement) {
                    return k;
                }
                k++;
            }
            return -1;
        };
    }
})();

1
Bilgiçlik taslayan ama MDN sadece Mozilla değil. Mozilla personelinin yanı sıra gönüllüler içeren, herkesin katılabileceği ve katkıda bulunabileceği topluluk odaklı bir projedir.
ste2425


2

Bu benim uygulamamdı. Temel olarak, bunu sayfadaki diğer komut dosyalarından önce ekleyin. yani Internet Explorer 8 için küresel bir çözüm için master. Ben de çerçeveler bir sürü kullanılan görünüyor trim fonksiyonu ekledi.

<!--[if lte IE 8]>
<script>
    if (!Array.prototype.indexOf) {
        Array.prototype.indexOf = function(obj, start) {
            for (var i = (start || 0), j = this.length; i < j; i++) {
                if (this[i] === obj) {
                    return i;
                }
            }
            return -1;
        };
    }

    if(typeof String.prototype.trim !== 'function') {
        String.prototype.trim = function() {
            return this.replace(/^\s+|\s+$/g, '');
        };
    };
</script>
<![endif]-->

2

benim için çalışıyor.

if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(elt /*, from*/) {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)? Math.ceil(from) : Math.floor(from);
    if (from < 0)
    from += len;

    for (; from < len; from++) {
      if (from in this && this[from] === elt)
        return from;
    }
    return -1;
  };
}

1

Underscore.js ile

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.