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

IE11报错:Object不支持indexOf方法,其他浏览器运行正常

解决IE11中动态特性检测脚本的SCRIPT438错误

你的问题核心是变量名冲突和回调参数传递错误,导致IE11里本该是字符串的检测项被当成了对象,进而触发indexOf不存在的报错。让我一步步拆解问题并给出修复方案:

错误根源分析

1. 函数参数名与外层变量重名

在dynamicPolyfill函数的forEach循环里,你用了和外层数组同名的参数tocheck:

tocheck.forEach( function(tocheck){
  checkPromises.push(checking(tocheck))
} )

在IE11这种旧浏览器的作用域机制下,这个参数会覆盖外层的数组变量,导致循环中传入checking函数的不是数组里的字符串项,而是一个异常对象,自然没有indexOf方法。

2. Promise polyfill的onload回调参数错误

在promiFill函数里,你给onload回调加了三个参数,但实际上onload回调的第一个参数是event对象,不是你传入的tocheck等参数:

promPolyfill.onload = function(tocheck, scriptToPolyfill, functionToRunonLoad) {
  dynamicPolyfill(tocheck, scriptToPolyfill, functionToRunonLoad);
}

这会导致dynamicPolyfill收到的tocheck是event对象,而非原始的特性数组,后续所有检测逻辑都会出错。

3. 不必要的String对象创建

在checking函数里,你用new Object(split[split.length - 1])把字符串转成了String对象:

var lastWord = new Object(split[split.length - 1]);

虽然现代浏览器能兼容,但IE里的String对象和原始字符串在in操作符的判断上可能有差异,而且完全没必要这么做,直接用原始字符串即可。

修复后的完整代码

dynamicPolyfill( 
  ['IntersectionObserver', 'IntersectionObserverEntry', 'Object.assign', 'Array.copyWithin'] 
  ,'https://cdn.jsdelivr.net/npm/quicklink@1.0.0/dist/quicklink.umd.js' 
  ,'quicklink()' 
)
function dynamicPolyfill(tocheck, scriptToPolyfill, functionToRunonLoad) {
  if(typeof Promise !== "undefined"){
    var checkPromises = [];
    if(Array.isArray(tocheck)) {
      // 修复:参数名改为item,避免与外层数组重名
      tocheck.forEach( function(item){
        checkPromises.push(checking(item))
      } )
    } else {
      checkPromises.push(checking(tocheck))
    }
    checkPromises = checkPromises.filter(function(p){return p !== undefined}).join(' ');
    loadPolyfill(checkPromises, scriptToPolyfill, functionToRunonLoad)
  } else {
    promiFill(tocheck, scriptToPolyfill, functionToRunonLoad);
  }
}
function promiFill(tocheck, scriptToPolyfill, functionToRunonLoad){
  var promPolyfill = document.createElement('script');
  promPolyfill.src = ('https://polyfill.io/v3/polyfill.min.js?features=Promise');
  document.body.appendChild(promPolyfill);
  promPolyfill.onerror = function(response) {
    console.error("Polyfilling promise failed", response);
  }
  // 修复:直接引用外层变量,避免错误传递参数
  promPolyfill.onload = function() {
    dynamicPolyfill(tocheck, scriptToPolyfill, functionToRunonLoad);
  }
}
function checking(check){
  var splitChars = '.';
  // 防御性转换:确保check是字符串类型
  check = String(check);
  if (!(check in window)) {
    if (check.indexOf(splitChars) >= 0) {
      var split = check.split('.');
      var currentObj = window[split[0]];
      var hasProperty = true;
      // 修复:逐层遍历嵌套属性,确保检测准确
      for(var i = 1; i < split.length; i++){
        if(!currentObj || !(split[i] in currentObj)){
          hasProperty = false;
          break;
        }
        currentObj = currentObj[split[i]];
      }
      if(!hasProperty){
        return check;
      }
    } else {
      return check;
    }
  }
}
function loadPolyfill(url, scriptToPolyfill, functionToRunonLoad) {
  if(url !== "") {
    var polyfill = document.createElement('script');
    polyfill.src = ('https://polyfill.io/v3/polyfill.min.js?features='+encodeURIComponent(url));
    document.body.appendChild(polyfill);
    polyfill.onerror = function(response) {
      console.error("Loading the polyfill(s) failed!", response);
    }
    polyfill.onload = function() {
      loadMyScript(scriptToPolyfill, functionToRunonLoad)
    }
  } else {
    loadMyScript(scriptToPolyfill, functionToRunonLoad)
  }
}
function loadMyScript(url, functionToRunonLoad) {
  if(Array.isArray(url)) {
    var promises = [];
    url.forEach( function(item){
      promises.push(nonblankURL(item));
    } );
    Promise.all(promises)
    .then( function() {
      initialiseMyScript(functionToRunonLoad)
    } ).catch(function(error){return error})
  } else if (!Array.isArray(url) && url !== null && url !== '') {
    nonblankURL(url)
    .then( function() {
      initialiseMyScript(functionToRunonLoad)
    } ).catch(function(error){return error})
  } else {
    initialiseMyScript(functionToRunonLoad)
  }
}
function nonblankURL(uri){
  return new Promise( function(resolve, reject) {
    var thescript = document.createElement('script');
    thescript.src = encodeURI(uri);
    document.body.appendChild(thescript);
    thescript.onerror = function(response) {
      return reject("Loading the script failed!", response);
    }
    thescript.onload = function() {
      return resolve(uri);
    }
  } )
}
function initialiseMyScript(functionToRunonLoad) {
  if(Array.isArray(functionToRunonLoad)) {
    functionToRunonLoad.forEach( function(item){
      initScript(item)
    } )
  } else {
    initScript(functionToRunonLoad)
  }
  function initScript(fn) {
    try {
      // 修复:正确执行函数调用字符串
      new Function(fn)();
    } catch(err) {
      console.error('There was an error: ', err, err.name, err.stack);
    }
  }
}

额外修复点说明

  • 在checking函数开头加了check = String(check)的防御性转换,确保即使传入非字符串也能处理。
  • 优化了嵌套属性的检测逻辑,原来的判断只检查了最后一个属性,现在会逐层遍历嵌套的属性链,比如Object.assign会先检查window.Object是否存在,再检查Object.assign是否存在。
  • 修复了initScript函数的执行逻辑:原来的window[fn]对于'quicklink()'这种字符串是无效的,改成用new Function(fn)()来正确执行函数调用字符串。

这样修改后,脚本应该能在IE11及其他现代浏览器中正常运行,正确检测特性并加载对应的polyfill。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:58:35