本文屬於亂侃,其中語言可能包含語句不通甚至顛三倒四先後不搭的部分。如引發各位看官的不適請見諒前端
因而 Array.prototype.flatten
終於變成 Array.prototype.flat
了:https://github.com/tc39/propo...。方法名變成了一個名詞或形容詞。git
我相信這不是標準制定者所情願的(雖然有人 強行 解釋了一下)。萬惡之源就是這個叫作 Mootools 的庫。我沒有用過,可是據說在多年之前的國外被普遍使用。我不想細談其內部細節,有興趣的能夠看谷歌的這篇博文:https://developers.google.com...github
其實相似事情以前就發生過一次。問題出在同一個庫身上,相同的解決方案:Array.prototype.contains
最終變成了 Array.prototype.includes
web
所謂兼容性就是抗歷史包袱。若是一個新版本瀏覽器發佈致使用戶常常瀏覽的網站掛掉,他們不會認爲這是網站的不對——他們根本不知道相似 Mootools
這種奇葩的存在。他們只知道:我原來用得好好的,怎麼升級以後就壞了?從而加固「跟新有風險,升級需謹慎」的印象,甚至造成「升級恐懼症」。瀏覽器
其餘語言或多或少都有一些歷史包袱,異常沉重的有如 C++,可是這類編譯型語言一旦被編譯爲目標代碼,兼容性包袱便轉拋給了操做系統。而前端代碼不同,他們被瀏覽器下載到了客戶端解釋(或預編譯)執行,語言級別的包袱會一直持續下去。語言設計者們已經作過了嘗試,好比這個神奇的 'use strict'
,可是它永遠不可能默認開啓。網站
因此 Mootools
那幫人在私自擴展原生對象的原型屬性時,有沒有想到着多是一件會阻礙人類文明的發展進程的嚴重問題呢?google
仍是補充說明此次 smoothgate 事件的原因。操作系統
Firefox 基於 Array.prototype.flatten 提議(舊版本,如今已經改成 flat)發佈了支持該 API 的新版瀏覽器,致使了至少一個著名站點出現了異常。prototype
Firefox 提供的 Array.prototype.flatten
實現並無 bug,問題在於網站使用的一個叫 Mootools 的庫。它提供了本身 非標準的 Array.prototype.flatten
版本實現。設計
Array.prototype.flatten = /* 非標準實現 */;
Mootools
提供的實現跟標準不一樣,然而這不是問題所在。Mootools
會強制覆蓋瀏覽器原生的 Array.prototype.flatten
實現,依賴 Mootools
的 Array.prototype.flatten
實現的網站並不會由於原生版本和 Mootools
版本不一致而產生問題。
然而不幸的是 Mootools
還作了一件噁心的事情:它會把全部自定義的 Array.prototype
下方法實現複製到 Elements.prototype
下(Elements
是 Mootools
提供的自定義 API)。
for (var key in Array.prototype) { Elements.prototype[key] = Array.prototype[key]; }
for-in
循環只會遍歷 可枚舉的(enumerable)的屬性,例如 Array.prototype.sort
、Array.prototype.push
這些原生的方法都是默認不可枚舉的(enumerable: false
),新的 Array.prototype.flatten
一樣如此。Mootools
用本身的實現覆蓋了原生的 Array.prototype.flatten
,可是並無改變方法的 enumerable
屬性——Array.prototype.flatten
仍然是不可枚舉的,致使 Array.prototype.flatten
不會被複制到 Elements.prototype
下。
因而:全部依賴 Elements.prototype.flatten
的代碼所有掛掉了。有人在 TC39 的官方 github 倉庫發了個 PR 戲謔說建議把 flatten
更名爲 smooth
,引起大討論,甚至有人信覺得真致使事件愈加擴大。因而 Google Update 官博專門發文闢謠。