Javascript Internet Explorer 上的 Array.from

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36810940/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 19:35:05  来源:igfitidea点击:

Array.from on the Internet Explorer

javascriptarraysangularjsinternet-explorer

提问by Robert J.

I have a problem with my angular app on the Internet Explorer. It runs everywhere without a problem (Chrome, Mozilla, Edge), but on on the IE.

我在 Internet Explorer 上的 angular 应用程序有问题。它在任何地方都可以正常运行(Chrome、Mozilla、Edge),但可以在 IE 上运行。

I have analyzed with the Developer Explorer where the error is and it returned that the error occurs on the following line:

我已经使用开发人员资源管理器分析了错误所在,并返回错误发生在以下行:

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

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

Where this is the following error message I am getting:

这是我收到的以下错误消息:

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

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

What I am doing there is that I have a Set()named tmpwhich contains the following data:

我在那里做的是我有一个包含以下数据的Set()命名tmp

enter image description here

在此处输入图片说明

Afterwards I am simply creating a simple array object from this Set.

之后我只是从 this 创建一个简单的数组对象Set

How can I solve this problem?

我怎么解决这个问题?

EDIT

编辑

Based on the recommendations I have added the following code to my app:

根据建议,我已将以下代码添加到我的应用程序中:

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;
    };
  }());
}

回答by Ali Mamedov

Array.fromnot supported in the following document modes: Quirks, Internet Explorer 6 standards, Internet Explorer 7 standards, Internet Explorer 8 standards, Internet Explorer 9 standards, Internet Explorer 10 standards, Internet Explorer 11 standards. Not supported in Windows 8.1 (compatibility reference)

Array.from以下文档模式不支持:Quirks、Internet Explorer 6 标准、Internet Explorer 7 标准、Internet Explorer 8 标准、Internet Explorer 9 标准、Internet Explorer 10 标准、Internet Explorer 11 标准。Windows 8.1 不支持(兼容性参考

Just add the code below to your page (JS code was copied from developer.mozilla.org). It will emulate an ES6's Array.frommethod.

只需将下面的代码添加到您的页面(JS 代码是从 developer.mozilla.org 复制的)。它将模拟 ES6 的Array.from方法。

Array.from was added to the ECMA-262 standard in the 6th edition; as such it may not be present in other implementations of the standard. You can work around this by inserting the following code at the beginning of your scripts, allowing use of Array.from in implementations that don't natively support it. 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.

Array.from 在第 6 版中被添加到 ECMA-262 标准中;因此,它可能不会出现在标准的其他实现中。您可以通过在脚本的开头插入以下代码来解决此问题,允许在本机不支持它的实现中使用 Array.from。该算法正是 ECMA-262,第 6 版中指定的算法,假设 Object 和 TypeError 具有其原始值,并且 callback.call 评估为 Function.prototype.call 的原始值。此外,由于真正的可迭代对象不能被 polyfill,因此该实现不支持 ECMA-262 第 6 版中定义的通用可迭代对象。

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;
    };
  }());
}

回答by Valentine Shi

I faced the same issue. Looked at the polyfill and it is threatening huge. Here is 2 lines short solution.

我遇到了同样的问题。看着 polyfill,它威胁巨大。这是 2 行简短的解决方案。

The OP basically needs to create simple array from his array-like object. I used to my taste the most efficient 2 lines plain forloop (I had to make array from HTML DOM nodelist array-like object, same applicable to JavaScript argumentsobject).

OP 基本上需要从他的类数组对象创建简单的数组。我习惯于使用最高效的 2 行纯for循环(我必须从 HTML DOM 节点列表类数组对象创建数组,同样适用于 JavaScriptarguments对象)。

For the OP's case it could sound this way:

对于 OP 的情况,它听起来可能是这样的:

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

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

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

Make it separate function and you get 3 lines universal reusable solution for the IE<9 case.

使其独立功能,您将获得 3 行通用可重用解决方案,适用于 IE<9 的情况。

Here is how the separate function may look like:

下面是分离函数的样子:

/**
 * @param arr The array | array-like data structure.
 * @param callback The function to process each element in the 'arr'.
 * The callback signature and usage is assumed similar to the 
 * native JS 'forEach' callback argument usage.
 */
function customEach(arr, callback) {
    'use strict';
    var l = arr.length;
    for (var i = 0; i < l; i++) {
        callback(arr[i], i, arr);
    }
};

PS: here is the relevant description for forEach callbackto see how to use the customEachcallback.

PS:这里是forEach回调的相关说明,看看如何使用customEach回调。

回答by Nina Scholz

While it's not supported on IE, you may use the polyfillfrom MDN.

虽然它不支持IE浏览器,你可以使用填充工具从MDN。