本文属于乱侃,其中语言可能包含语句不通甚至颠三倒四先后不搭的部分。如引发各位看官的不适请见谅前端
因而 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 官博专门发文辟谣。