Safari&;中的Javascript ES6类型错误;即

Safari&;中的Javascript ES6类型错误;即,javascript,safari,ecmascript-6,typeerror,polyfills,Javascript,Safari,Ecmascript 6,Typeerror,Polyfills,我正在使用由其他人编写的Javascript代码,他们在Wordpress网站上使用ES6。它通过Ajax调用在DOM中显示数据,DOM适用于Chrome和Firefox,但由于某些原因,Safari在控制台中出现以下错误: TypeError: document.querySelectorAll(".js_zip-lookup__submit").forEach is not a function. (In 'document.querySelectorAll(".js_zip-lookup_

我正在使用由其他人编写的Javascript代码,他们在Wordpress网站上使用ES6。它通过Ajax调用在DOM中显示数据,DOM适用于Chrome和Firefox,但由于某些原因,Safari在控制台中出现以下错误:

TypeError: document.querySelectorAll(".js_zip-lookup__submit").forEach is not a function. (In 'document.querySelectorAll(".js_zip-lookup__submit").forEach(function(e){e.addEventListener("click",function(){displayResults(e.parentNode.querySelector(".zip-lookup__input").value)})})', 'document.querySelectorAll(".js_zip-lookup__submit").forEach' is undefined)
这就是功能:

function finderInit(){
  document.querySelectorAll('.js_zip-lookup__submit').forEach(function(button){
    button.addEventListener('click', function(){
      const zip = button.parentNode.querySelector('.zip-lookup__input').value;
      displayResults(zip);
    });
  });

  document.querySelectorAll('.zip-lookup').forEach(function(form){
    form.addEventListener('submit', function(e){
      e.preventDefault();
      const zip = form.querySelector('.zip-lookup__input').value;
      displayResults(zip);
    })
  });
}

我不太清楚为什么Safari会有这个问题,而Chrome/FF甚至没有在控制台中记录关于这个特定部分的任何错误,而且它工作得很好。我知道这应该是一些浏览器兼容性问题,但到目前为止还没有找到太多的信息

document.querySelectorAll
返回
节点列表
对象,而不是数组。正如它所说,
NodeList
forEach
方法,但它没有得到很好的支持,这就是为什么它可以在最近的Firefox和Chrome中使用,但不能在其他浏览器(Safari)中使用的原因:

尽管NodeList不是数组,但可以使用forEach()对其进行迭代。一些较旧的浏览器尚未实现此方法

要以兼容的方式迭代节点列表和其他迭代器,应使用
Array.from
(可以在旧浏览器中多填充):


正如@Estus所提到的,较早版本的Safari没有在nodelist对象上实现
.forEach
。但是,
Array.prototype.forEach
在规范中定义为通用:

forEach函数故意是泛型的;它不要求其此值是数组对象。因此,它可以被转移到其他类型的对象中用作方法。forEach函数能否成功应用于主机对象取决于实现

因此,一个可行的解决方案是在nodelist上调用
Array.prototype.forEach
,并将要执行的函数传递给它。作为精简(且便宜)的测试用例:

var col=document.getElementsByTagName(“p”);
//col.forEach(函数(el){document.write(el.id)});
调用(col,函数(el){document.write(el.id)})


我尝试了Array.prototype的许多变体,但唯一解决IE&Safari兼容性问题的方法是在下面包含此polypill片段,解决方案可在:


这会在哪个版本的Safari上失败?@AndrewLi,实际上会失败,但可能不是在所有浏览器中都会失败。安玛:你用什么版本的Safari测试过这个?在Safari之前的版本中,它可能受支持,也可能不受支持10@PatrickEvans啊,是的。谢谢你的提醒。你是对的,它在Safari 10中工作,但在控制台中仍然记录有TypeError。而其功能与下面的Safari 9完全不同。我在自己的Mac电脑旁使用Browserstack。这确实消除了TypeError,它在Safari 10中有效,但不适用于9及以下版本。是否有替代方案来覆盖兼容性?如果可能的话,对于IE也是如此?正如前面所说,Array.from是可多填充的。使用多填充物,例如。默认情况下,任何web项目都应该这样做。对于将来可能遇到这种情况的人,理想情况下,
core js
也会在这里使用polyfill
。forEach
,但我们会看到。实芯-js@2.4.1已经作为babel软件包的一部分包含在该项目中,但仍然没有。forEach polyfill…@Amma loganfsmyth引用的问题说,NodeList forEach polyfill还没有出现。如答案所示,使用Array.from。谢谢@Traktor。我使用了以下代码,但仍然不适合IE inside Browsertack。还有别的选择吗?var zipSubmit=document.querySelectorAll('.js_zip-lookup__submit');Array.prototype.forEach.call(zipSubmit,函数(按钮){button.addEventListener('click',function(){const zip=button.parentNode.querySelector('.zip-lookup_uinput')).value;displayResults(zip);});很难说没有错误详细信息和HTML代码。如果Browserstack没有帮助,请尝试在运行IE的windows计算机上测试,并打开开发工具(F12)。更改仿真模式以测试较旧的浏览器。如果没有显示任何内容,请编写for循环以添加事件侦听器,并证明其余代码正常工作
.forEach
是ES5.1,在IE8或更早版本中不起作用。
Array.from(document.querySelectorAll(".js_zip-lookup__submit")).forEach(...);
(function () {
    if ( typeof NodeList.prototype.forEach === "function" ) return false;
    NodeList.prototype.forEach = Array.prototype.forEach;
})();