2016-04-23 2 views
11

У меня проблема с моим угловым приложением в Internet Explorer. Он работает везде без проблем (Chrome, Mozilla, Edge), но включен в IE.Array.from в Internet Explorer

Я проанализировал с Developer Explorer, где ошибка есть и он вернулся, что ошибка возникает в следующей строке:

myDataSet[index - 1].data = Array.from(tmp);

Где это следующее сообщение об ошибке я получаю:

Object does not support property or method from at Anonymous function....(etc.)

что я делаю там, что у меня есть Set() имени tmp, который содержит следующие данные:

enter image description here

Потом я просто создать простой массив объектов из этого Set.

Как я могу решить эту проблему?

EDIT

На основе рекомендаций, я добавил следующий код в мое приложение:

if (!Array.from) { 
    Array.from = (function() { 
    var toStr = Object.prototype.toString; 
    var isCallable = function (fn) { 
     return typeof fn === 'function' || toStr.call(fn) === '[object Function]'; 
    }; 
    var toInteger = function (value) { 
     var number = Number(value); 
     if (isNaN(number)) { return 0; } 
     if (number === 0 || !isFinite(number)) { return number; } 
     return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); 
    }; 
    var maxSafeInteger = Math.pow(2, 53) - 1; 
    var toLength = function (value) { 
     var len = toInteger(value); 
     return Math.min(Math.max(len, 0), maxSafeInteger); 
    }; 

    // The length property of the from method is 1. 
    return function from(arrayLike/*, mapFn, thisArg */) { 
     // 1. Let C be the this value. 
     var C = this; 

     // 2. Let items be ToObject(arrayLike). 
     var items = Object(arrayLike); 

     // 3. ReturnIfAbrupt(items). 
     if (arrayLike == null) { 
     throw new TypeError("Array.from requires an array-like object - not null or undefined"); 
     } 

     // 4. If mapfn is undefined, then let mapping be false. 
     var mapFn = arguments.length > 1 ? arguments[1] : void undefined; 
     var T; 
     if (typeof mapFn !== 'undefined') { 
     // 5. else 
     // 5. a If IsCallable(mapfn) is false, throw a TypeError exception. 
     if (!isCallable(mapFn)) { 
      throw new TypeError('Array.from: when provided, the second argument must be a function'); 
     } 

     // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined. 
     if (arguments.length > 2) { 
      T = arguments[2]; 
     } 
     } 

     // 10. Let lenValue be Get(items, "length"). 
     // 11. Let len be ToLength(lenValue). 
     var len = toLength(items.length); 

     // 13. If IsConstructor(C) is true, then 
     // 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len. 
     // 14. a. Else, Let A be ArrayCreate(len). 
     var A = isCallable(C) ? Object(new C(len)) : new Array(len); 

     // 16. Let k be 0. 
     var k = 0; 
     // 17. Repeat, while k < len… (also steps a - h) 
     var kValue; 
     while (k < len) { 
     kValue = items[k]; 
     if (mapFn) { 
      A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); 
     } else { 
      A[k] = kValue; 
     } 
     k += 1; 
     } 
     // 18. Let putStatus be Put(A, "length", len, true). 
     A.length = len; 
     // 20. Return A. 
     return A; 
    }; 
    }()); 
} 

ответ

23

Array.from не поддерживается в следующих режимах документов: Причуды, Internet Explorer 6 стандартов, Internet Explorer 7, стандарты Internet Explorer 8, стандарты Internet Explorer 9, стандарты Internet Explorer 10, стандарты Internet Explorer 11. Не поддерживается в Windows 8.1.

Просто добавьте код на свою страницу (JS code was copied from developer.mozilla.org). Он будет эмулировать метод ES12 Array.from.

Array.from был добавлен к стандарту ECMA-262 в шестом издании; как , такой он может отсутствовать в других реализациях стандарта. Вы можете обойти это, вставив следующий код на начало в начало ваших сценариев, позволяя использовать Array.from в версиях , которые его не поддерживают. Этот алгоритм имеет значение , точно указанное в ECMA-262, 6-е издание, при условии, что объекты и TypeError имеют свои исходные значения и что callback.call оценивает исходное значение Function.prototype.call. В дополнении , поскольку истинные итерации не могут быть заполнены, эта реализация не поддерживает общие итерации, как определено в 6-е издание ECMA-262.

if (!Array.from) { 
    Array.from = (function() { 
    var toStr = Object.prototype.toString; 
    var isCallable = function (fn) { 
     return typeof fn === 'function' || toStr.call(fn) === '[object Function]'; 
    }; 
    var toInteger = function (value) { 
     var number = Number(value); 
     if (isNaN(number)) { return 0; } 
     if (number === 0 || !isFinite(number)) { return number; } 
     return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); 
    }; 
    var maxSafeInteger = Math.pow(2, 53) - 1; 
    var toLength = function (value) { 
     var len = toInteger(value); 
     return Math.min(Math.max(len, 0), maxSafeInteger); 
    }; 

    // The length property of the from method is 1. 
    return function from(arrayLike/*, mapFn, thisArg */) { 
     // 1. Let C be the this value. 
     var C = this; 

     // 2. Let items be ToObject(arrayLike). 
     var items = Object(arrayLike); 

     // 3. ReturnIfAbrupt(items). 
     if (arrayLike == null) { 
     throw new TypeError("Array.from requires an array-like object - not null or undefined"); 
     } 

     // 4. If mapfn is undefined, then let mapping be false. 
     var mapFn = arguments.length > 1 ? arguments[1] : void undefined; 
     var T; 
     if (typeof mapFn !== 'undefined') { 
     // 5. else 
     // 5. a If IsCallable(mapfn) is false, throw a TypeError exception. 
     if (!isCallable(mapFn)) { 
      throw new TypeError('Array.from: when provided, the second argument must be a function'); 
     } 

     // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined. 
     if (arguments.length > 2) { 
      T = arguments[2]; 
     } 
     } 

     // 10. Let lenValue be Get(items, "length"). 
     // 11. Let len be ToLength(lenValue). 
     var len = toLength(items.length); 

     // 13. If IsConstructor(C) is true, then 
     // 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len. 
     // 14. a. Else, Let A be ArrayCreate(len). 
     var A = isCallable(C) ? Object(new C(len)) : new Array(len); 

     // 16. Let k be 0. 
     var k = 0; 
     // 17. Repeat, while k < len… (also steps a - h) 
     var kValue; 
     while (k < len) { 
     kValue = items[k]; 
     if (mapFn) { 
      A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); 
     } else { 
      A[k] = kValue; 
     } 
     k += 1; 
     } 
     // 18. Let putStatus be Put(A, "length", len, true). 
     A.length = len; 
     // 20. Return A. 
     return A; 
    }; 
    }()); 
} 
+0

Благодарим вас за это объяснение. Не могли бы вы посоветовать, какой код использовать для замены моего «Array.from», пожалуйста? –

+0

Я обновил свой ответ. Просто скопируйте код JavaScript на свою страницу. Например, к основному файлу JS. И ваша проблема будет решена! –

+0

Вы можете попробовать 'myDataSet [index - 1] .data = Array.prototype.slice.call (tmp);' – Redu

4

Хотя это не поддерживается на IE, вы можете использовать polyfill от MDN.

3

Я столкнулся с той же проблемой. Посмотрел на полиполк, и это грозит огромным количеством. Вот два коротких решения.

OP в принципе должен создать простой массив из своего массивно-подобного объекта.Я использовал на свой вкус наиболее эффективные 2 строки простой for цикл (мне пришлось сделать массив из объекта DOM nodelist arraylike, который применим к JavaScript arguments).

В случае Ор в это может звучать так:

var temp_array = [], 
    length = tmp.Set.length; 

for (var i = 0; i < length; i++) { 
    temp_array.push(tmp.Set[i]); 
} 

// Here you get the normal array "temp_array" containing all items 
// from your `tmp.Set`. 

Сделать отдельную функцию, и вы получите 3 линии универсальное решение для случая IE < 9.