forEach 函數在最近的Microsoft 瀏覽器中不起作用
在嘗試為Web 應用程式中的產品選擇建立腳本時,開發人員遇到了Internet Explorer 11 和Microsoft Edge 中出現錯誤。錯誤訊息表明 forEach 函數不受支持,儘管據報導該函數在 IE9 及更高版本中可用。
探索問題
forEach 方法通常是用於迭代數組元素並對每個元素應用函數。在這種情況下,開發人員利用了從產品配置中選擇顏色選項的方法。然而,經過調查,發現以下程式碼片段:
var color_btns = document.querySelectorAll('#color > p'); color_btns.forEach(function(color) { color.onclick = function () { color_btns.forEach(function(element) { if (element.classList.contains('selected')) { element.classList.remove('selected'); } }); color.classList.add('selected'); document.querySelector('#f_color').value = color.dataset.id; }; });
在Internet Explorer 和Microsoft Edge 中沒有按預期運行,拋出錯誤,表明forEach 函數不是NodeList 的屬性
問題原因
進一步研究發現,querySelectorAll 及類似方法傳回的物件類型NodeList 和HTMLCollection 是不是真正的數組,而是可迭代的。在 JavaScript 中,可迭代物件是可以使用 for-of 連結、擴充運算子或解構賦值進行迭代的物件。
NodeList 物件最近獲得了對 forEach 方法的支持,但 HTMLCollection 物件沒有,也不期望支援它。這是由於向後相容性問題,因為將 forEach 方法新增至 HTMLCollection 可能會破壞現有程式碼。
Polyfilling forEach
要解決此問題,建議polyfill NodeList 物件的 forEach 方法。 Polyfilling 涉及為本機不支援的物件新增方法。下面的程式碼片段可以為NodeList 填入forEach:
if (typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype.forEach) { NodeList.prototype.forEach = Array.prototype.forEach; }
直接賦值,如上面的程式碼所示,是可能的,因為enumerable、configurable 和writable 都應該為true,而且它是一個value 屬性。
Polyfilling Iterability
此外,NodeList 物件也可以變得可迭代,以支援使用 for-of 動態和展開運算子對其進行迭代。這可以透過以下polyfill來實現:
if (typeof Symbol !== "undefined" && Symbol.iterator && typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype[Symbol.iterator]) { Object.defineProperty(NodeList.prototype, Symbol.iterator, { value: Array.prototype[Symbol.iterator], writable: true, configurable: true }); }
使用Polyfill的範例
透過合併這些polyfill,可以修改原始程式碼以在所有支援的環境中無縫運行瀏覽器:
// Polyfilling forEach for NodeList if (typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype.forEach) { NodeList.prototype.forEach = Array.prototype.forEach; } // Polyfilling iterability for NodeList if (typeof Symbol !== "undefined" && Symbol.iterator && typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype[Symbol.iterator]) { Object.defineProperty(NodeList.prototype, Symbol.iterator, { value: Array.prototype[Symbol.iterator], writable: true, configurable: true }); } var color_btns = document.querySelectorAll('#color > p'); color_btns.forEach(function(color) { color.onclick = function () { color_btns.forEach(function(element) { if (element.classList.contains('selected')) { element.classList.remove('selected'); } }); color.classList.add('selected'); document.querySelector('#f_color').value = color.dataset.id; }; });
此更新的程式碼片段應在所有瀏覽器中如預期執行,包括Internet Explorer 和Microsoft Edge。
以上是為什麼 forEach 函數在 Internet Explorer 和 Microsoft Edge 中不起作用?的詳細內容。更多資訊請關注PHP中文網其他相關文章!