近期的 smoothgate 事件有感乱侃

本文属于乱侃,其中语言可能包含语句不通甚至颠三倒四先后不搭的部分。如引发各位看官的不适请见谅前端


因而 Array.prototype.flatten 终于变成 Array.prototype.flat 了:https://github.com/tc39/propo...。方法名变成了一个名词或形容词。git

我相信这不是标准制定者所情愿的(虽然有人 强行 解释了一下)。万恶之源就是这个叫作 Mootools 的库。我没有用过,可是据说在多年之前的国外被普遍使用。我不想细谈其内部细节,有兴趣的能够看谷歌的这篇博文:https://developers.google.com...github

其实相似事情以前就发生过一次。问题出在同一个库身上,相同的解决方案:Array.prototype.contains 最终变成了 Array.prototype.includesweb

所谓兼容性就是抗历史包袱。若是一个新版本浏览器发布致使用户常常浏览的网站挂掉,他们不会认为这是网站的不对——他们根本不知道相似 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 实现,依赖 MootoolsArray.prototype.flatten 实现的网站并不会由于原生版本和 Mootools 版本不一致而产生问题。

然而不幸的是 Mootools 还作了一件恶心的事情:它会把全部自定义的 Array.prototype 下方法实现复制到 Elements.prototype 下(ElementsMootools 提供的自定义 API)。

for (var key in Array.prototype) {
  Elements.prototype[key] = Array.prototype[key];
}

for-in 循环只会遍历 可枚举的(enumerable)的属性,例如 Array.prototype.sortArray.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 官博专门发文辟谣。

相关文章
相关标签/搜索