0

can I convert , in Javascript, an object into an array in Internet Explorer? I read that the method Array.from(obj) is not supported from IE. It is correct?

Thank you

John Slegers
  • 45,213
  • 22
  • 199
  • 169
Raul
  • 115
  • 5
  • 16
  • You can find polyfills to support Array.from(). See: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Array/from – marwils Jun 29 '17 at 15:00
  • Possible duplicate of [Array.from on the Internet Explorer](https://stackoverflow.com/questions/36810940/array-from-on-the-internet-explorer) – Krzysztof Janiszewski Jun 15 '18 at 09:15

4 Answers4

3

You can verify for yourself on On Mozilla's MDN that Array.from() isn't supported by IE :

enter image description here

On that same page, you can also find the following polyfill to add support of Array.from() to browsers that don't support it natively :

// Production steps of ECMA-262, Edition 6, 22.1.2.1
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;
    };
  }());
}

Note that it comes with the following remarks :

This algorithm is exactly the one specified in ECMA-262, 6th edition, assuming Object and TypeError have their original values and that callback.call evaluates to the original value of Function.prototype.call. In addition, since true iterables can not be polyfilled, this implementation does not support generic iterables as defined in the 6th edition of ECMA-262.

That means that there are a few caveats, but it should be more than sufficient for most purposes!

John Slegers
  • 45,213
  • 22
  • 199
  • 169
  • I tried this solution, but the condition (!Array.from) is false in my app, and it doesn't entry into the function. So the generated array from the object will be empty... do you know which could be the problem? Sorry, but I am new in the Angular JS's world. – Raul Jun 30 '17 at 08:34
  • 1
    If `!Array.from` is `false`, that means your browser already supports `Array.from` and it doesn't need this polyfill. If your browser doesn't support `Array.from`, `!Array.from` will be `true` and this polyfill will add support for it. See [this article](http://www.programmerinterview.com/index.php/html5/html5-polyfill/) for more info on polyfills. – John Slegers Jul 04 '17 at 08:54
0

Yes, according to ECMAScript 6, this true for elder IE. You can find some polyfills listed there if you need this function & support for elder IE.

0

Array.from method is a method that came with ECMAScript 6

you can see on this page that the support for ECMAScript 6 in IE is not very good. Look at the examples in the below question for a solution to your problem

Converting a JS object to an array

0

As in JavaScript, array positions are like object properties (You can access objects with obj["property"]), you can just iterate over the properties of your object and push them onto an array.

For example:

//Example object
var obj = {
    prop1: "asd",
    prop2: "Another value",
    prop3: 5,
    funcprop: function(val){return val*2;}
}
//-----------

var i = 0;
var array = [];
for(prop in obj){
    array[i] = obj[prop];
    i++;
}

console.log(array); //Array [ "asd", "Another value", 5, funcprop() ]

Acording to MSDN, for..in syntax is valid since IE6.

Take this with care, as you will have property functions in the array positions also.

Alex Ruiz
  • 415
  • 2
  • 8