You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Jasmine测试时Array.from()无法正常工作的问题求助

解决Jasmine测试中Array.from()报TypeError的问题

嘿,我之前也碰到过类似的情况——明明在现代浏览器和Node里Array.from()用得好好的,一跑Jasmine测试就报错说它是undefined。大概率是测试环境的锅,我给你梳理下可能的原因和解决办法:

为什么会出现这个问题?

最常见的元凶是PhantomJS——很多老项目的Jasmine会用它当无头浏览器跑测试,但PhantomJS基于非常老旧的WebKit内核,根本不支持ES6的Array.from()方法。哪怕你的Node和Firefox都是新版的,测试环境的JS引擎跟不上,照样会报错。

另外一种可能是你的测试代码没经过转译,ES6特性直接跑到不支持的环境里了。

怎么解决?

方案1:换掉PhantomJS(推荐)

PhantomJS早就停止维护了,完全没必要再用它。换成现代的无头浏览器就行:

  • Chrome Headless:直接用Chrome的无头模式,支持所有ES6+特性,Jasmine很容易配置它。
  • Firefox Headless:同样靠谱,兼容性拉满。

方案2:给Array.from()加Polyfill

如果暂时没法换测试环境,那就给旧环境补个Polyfill,让它认识Array.from()。把这段MDN官方的Polyfill代码放到你的测试入口文件,或者被测试模块的最顶部:

// Array.from Polyfill (来自MDN)
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);
    };

    return function from(arrayLike/*, mapFn, thisArg */) {
      var C = this;
      var items = Object(arrayLike);
      if (arrayLike == null) {
        throw new TypeError("Array.from requires an array-like object - not null or undefined");
      }

      var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
      var T;
      if (typeof mapFn !== 'undefined') {
        if (!isCallable(mapFn)) {
          throw new TypeError('Array.from: when provided, the second argument must be a function');
        }
        if (arguments.length > 2) {
          T = arguments[2];
        }
      }

      var len = toLength(items.length);
      var A = isCallable(C) ? Object(new C(len)) : new Array(len);
      var k = 0;
      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;
      }
      A.length = len;
      return A;
    };
  }());
}

加了这个之后,旧环境就能像现代浏览器一样正常使用Array.from()了。

方案3:用Babel转译测试代码

如果你的项目本来就用Babel处理ES6,那得确保测试代码也被转译。可以在Jasmine配置里加Babel预处理,或者用@babel/preset-env自动把不支持的特性转成ES5代码。

验证一下

按上面的方法调整后,再跑你的测试代码:

var t = [1, 2, 3]; 
console.log(Array.from(t)); 
console.log(Array.from(baseObject.childNodes));

应该就能顺利执行,不会再报那个烦人的TypeError啦。

内容的提问来源于stack exchange,提问作者MVanOrder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:15:01