10

Non ho IE8, quindi sto testando IE8 da IE10. Quando passo a "standard IE8" per la modalità documento, la funzione mappa javascript di un oggetto array dà un errore javascript: L'oggetto non supporta la proprietà o il metodo 'map'La funzione array.map non è supportata negli standard IE8?

ma quando passo a "Standard" per documento modalità, non ci sono errori. Quale modalità devo testare sotto?

Se IE8 non supporta la funzione mappa, esiste un modo per emularlo?

+1

IE8 non supporta i metodi di matrice ES5. Puoi usare jQuery's ['$ .map()'] (http://api.jquery.com/jQuery.map/), o underscore's ['_.map()'] (http://underscorejs.org /#carta geografica). –

risposta

11

Non è supportato, ma MDN fornisce uno spessore molto vicino alla specifica:

// Production steps of ECMA-262, Edition 5, 15.4.4.19 
// Reference: http://es5.github.com/#x15.4.4.19 
if (!Array.prototype.map) { 
    Array.prototype.map = function(callback, thisArg) { 

    var T, A, k; 

    if (this == null) { 
     throw new TypeError(" this is null or not defined"); 
    } 

    // 1. Let O be the result of calling ToObject passing the |this| value as the argument. 
    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 IsCallable(callback) is false, throw a TypeError exception. 
    // See: http://es5.github.com/#x9.11 
    if (typeof callback !== "function") { 
     throw new TypeError(callback + " is not a function"); 
    } 

    // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. 
    if (thisArg) { 
     T = thisArg; 
    } 

    // 6. Let A be a new array created as if by the expression new Array(len) where Array is 
    // the standard built-in constructor with that name and len is the value of len. 
    A = new Array(len); 

    // 7. Let k be 0 
    k = 0; 

    // 8. Repeat, while k < len 
    while(k < len) { 

     var kValue, mappedValue; 

     // 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 
     if (k in O) { 

     // i. Let kValue be the result of calling the Get internal method of O with argument Pk. 
     kValue = O[ k ]; 

     // ii. Let mappedValue be the result of calling the Call internal method of callback 
     // with T as the this value and argument list containing kValue, k, and O. 
     mappedValue = callback.call(T, kValue, k, O); 

     // iii. Call the DefineOwnProperty internal method of A with arguments 
     // Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true}, 
     // and false. 

     // In browsers that support Object.defineProperty, use the following: 
     // Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true }); 

     // For best browser support, use the following: 
     A[ k ] = mappedValue; 
     } 
     // d. Increase k by 1. 
     k++; 
    } 

    // 9. return A 
    return A; 
    };  
} 
+0

Sapete perché controllano se "questo" è "null". Non vedo come sarebbe possibile. In realtà 'Array.prototype.map.call (null);' solleva un errore, tuttavia non riesco a essere in grado di impostare l'oggetto contesto su null quando si utilizza 'call' su funzioni non native? – plalx

+0

Il codice MDN tenta di implementare la specifica il più possibile, così mentre * questo * nei browser compatibili con ES3 come IE8 non può mai essere indefinito o nullo (o qualcosa di diverso da un oggetto), copre comunque quel caso perché non si sa mai cosa ambiente in cui verrà eseguito il codice. – RobG

+0

@RobG Sono d'accordo, tuttavia come mai le funzioni native, come 'map', sono state in grado di determinare che' this' era nullo? Potrebbe essere che il processo di invocazione sia leggermente diverso rispetto a quando si invocano funzioni non native? – plalx

2

IE8 non supporta i metodi di array ES5.

È possibile utilizzare il numero $.map() di jQuery o il carattere di sottolineatura _.map().


Se non stai utilizzando uno qualsiasi di questi librerie, è possibile utilizzare this polyfill on MDN.

1

No, non è implementato. Ma è possibile estendere prototipo Array da questo:

(function(fn){ 
    if (!fn.map) fn.map=function(f){var r=[];for(var i=0;i<this.length;i++)r.push(f(this[i]));return r} 
    if (!fn.filter) fn.filter=function(f){var r=[];for(var i=0;i<this.length;i++)if(f(this[i]))r.push(this[i]);return r} 
})(Array.prototype); 
4

Utilizzando jQuery.map():

if (!Array.prototype.map) { 
    Array.prototype.map = function (callback, thisArg) { 
     return $.isArray(thisArg) ? $.map(thisArg, callback) : []; 
    }; 
} 
Problemi correlati