JavaScript 社区由一个库激发的“smoosh门”事宜究竟怎么回事?

原文:
#SmooshGate FAQ

作者:
Mathias Bynens

smoosh?!发作了什么?!

一项名为 JavaScript 功用的提案 Array.prototype.flatten 证实与 Web 不兼容。在 Firefox Nightly 中宣布该功用会致使最少一个受欢迎的网站中缀。鉴于有题目的代码是普遍运用的 MooTools 库的一部分,极能够会有更多网站受到影响。(只管 MooTools 在 2018 年并不常用于新网站,但它曾异常盛行,而且依然存在于许多已正在运转的网站上。)

该提案笔者开顽笑地发起flatten 重命名为 smoosh,以防止兼容性题目。

然则,并不是一切人都晓得这是一个笑话,有些人最先毛病地以为这个新名字已被肯定,而且事变敏捷晋级。

Array.prototype.flatten 是什么?

Array.prototype.flatten 递归地将数组展根据指定的 depth 举办展平,depth 的默认值为 1

// Flatten one level:
const array = [1, [2, [3]]];
array.flatten();
// → [1, 2, [3]]

// Flatten recursively until the array contains no more nested arrays:
array.flatten(Infinity);
// → [1, 2, 3]

一样的发起还包含 Array.prototype.flatMap,犹如 Array.prototype.map 一样,能够在参数内里通报一个回调函数。

[2, 3, 4].flatMap((x) => [x, x * 2]);
// → [2, 4, 3, 6, 4, 8]

MooTools 致使了什么题目?

MooTools 定义了他们本身的非范例版本 Array.prototype.flatten

Array.prototype.flatten = /* non-standard implementation */;

MooTools 的 flatten 完成与发起的范例差别。然则,这并不是题目!当浏览器供应了原生的 Array.prototype.flatten 时,MooTools 会掩盖原生完成。这可确保依靠 MooTools 的代码按预期运转,不管原生 flatten 是不是可用。到如今为止还挺好!

不幸的是,发作了其他事变。MooTools 将其一切自定义数组要领复制到 Elements.prototypeElements 是 MooTools 特定的 API):

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

forin 遍历“可罗列”属性,个中不包含像原生要领 Array.prototype.sort,而是包含自定义的属性Array.prototype.foo = whatever。然则 – 背锅最先了 – 假如你掩盖了一个非罗列属性,比方 Array.prototype.sort = whatever,那末这个属性依然是不可罗列的。

如今,Array.prototype.flatten = mooToolsFlattenImplementation 建立一个罗列 flatten 属性,所以它以后会被复制到 Elements。然则,假如我们宣布原生版本的 flatten,它将变得不可罗列,而且不会被复制到 Elements如今,任何运用 MooTools 并依靠于 Elements.prototype.flatten 的代码都被损坏了

只管将原生 Array.prototype.flatten 变成可罗列能够会处理题目,但它能够会致使更多的兼容性题目。每一个依靠于 forin 遍历数组(这是一个蹩脚的做法,但它经常被运用)的网站会倏忽获得该 flatten 属性的轮回迭代。

这里更大的底层题目是修正内置对象。如今扩大当地原型一般被以为是一种不好的做法,因为它不能很好地与其他库和第三方代码连系。不要修正不属于你的对象!

我们为何不保存现有称号并突破收集?

1996 年,在 CSS 普遍传播之前,早在“HTML5”之前,Space Jam 网站就已最先运转了。本日,该网站已顺遂运转 22年了。

这是怎样做到的呢?这些年有没有人保护该网站,每次浏览器供应商宣布新功用时都邑更新它?

事实证实,“不要突破收集”是 HTML,CSS,JavaScript 和 Web 任何范例上都普遍运用的头号设想准绳。假如宣布新的浏览器功用致使现有网站停止事情,那对每一个人都不利:

  • 受影响网站的访问者倏忽获得一个损坏的用户体验;
  • 网站一切者从一个圆满的网站变成了一个没有功用的网站,而网站一切者却并没有转变任何东西;
  • 用户看到“只支撑 XXX 浏览器”以后切换浏览器,因而推出新功用的浏览器供应商失去了市场份额。
  • 一旦晓得兼容性题目,其他浏览器供应商谢绝完成此特征。致使某特征的范例与现实完成状况不符(“只是虚拟的作品”),这对范例化历程不利。

固然,回想起来 MooTools 做错了一件事 – 然则突破收集并不责罚它们(MooTools),而是会责罚用户。这些用户不晓得 MooTools 是什么。

或许,我们能够找到另一种处理方案,用户能够继承运用收集。

这是不是意味着没法从 Web 平台中删除不好的 API?

在极少数状况下,能够从收集中删除不良的功用。纵然仅仅弄清楚是不是能够删除一个功用也是异常辣手的事情,须要大批的遥测来量化有若干网页会转变他们的行动。然则,假如功用充足不安全,对用户有害,或许很少运用,则能够完成此操纵。

<applet><keygen>showModalDialog() 都是从 Web 平台胜利删除的毛病 API 的示例。

为何不修复 MooTools?

修补 MooTools 以便它不再扩大内置对象是个不错的主张。然则,它并没有处理手头的题目。纵然 MooTools 宣布补丁版本,一切运用它的现有网站也必需更新,如许兼容性题目才消逝。

能不能只更新网站中运用的 MooTools 副本?

在抱负状况下 MooTools 会宣布一个补丁,每一个运用 MooTools 的网站都邑在第二天奇异地更新。题目处理了,对吧?!

不幸的是,这是不现实的。纵然有人以某种体式格局识别了整套受影响的网站,也能够想法找到每一个网站的联络信息,胜利地与一切网站一切者联络并压服他们悉数实行更新(这能够意味着重构他们的网站完全的代码库),全部历程最多须要几年的时候。

请记着,这些网站许多都是旧的,可​​能没法保护。纵然保护职员依然在身旁,也能够他们不是像您一样的高技能 Web 开发职员。因为收集兼容性题目,我们不能愿望每一个人都去转变他们已运转了七八年的网站。

TC39 的事情流程是什么样的?

JavaScript 言语基于 ECMAScript 范例,TC39 是担任 JavaScript 言语更新生长的委员会

“Smoosh门”事宜使得一些人误以为“TC39 想要把 flatten 从新命名为 smoosh”,但这是一个没有很好沟通的笑话。重命名提案等严重决议计划不会被轻蔑,不会被单个人采用,而且相对不会在 GitHub 的批评上完成。

TC39 关于功用提案有着清楚得分级历程。ECMAScript 提案及其任何严重变动(包含要领更新)在 TC39 集会期间举办议论,而且须要全部委员会同意后方可正式提交。在这类状况下 Array.prototype.flatten 提案已阅历了好几个阶段的议论,一直到 Stage 3,表明该功用已预备幸亏 Web 浏览器中完成。实行历程当中涌现其他范例题目很罕见。在这类状况下,最主要的反应看法是在试图宣布它以后才有的:该特征在当前状态下突破了 Web。纵然浏览器宣布新功用后 TC39 的流程并没有完毕,就是因为这些难以预测的题目。

TC39 以协商一致的体式格局运作,这意味着委员会必需就任何新的变化杀青一致。纵然 smoosh 是一个庄重的发起,委员会成员好像也能够会阻挡,而是赞同运用更罕见的称号,比方 compactchain

flatten 重命名为 smoosh(纵然它不是一个笑话)从未在 TC39 集会上议论。因而,关于这个题目的官方 TC39 态度如今是未知的。在下次集会杀青共鸣之前,没有任何一个人能够代表一切 TC39 谈话。

TC39 集会一般由具有高度多样化背景的人士列席:一些人具有多年的编程言语设想履历,另一些人运用浏览器或 JavaScript 引擎事情,越来越多的 JavaScript 开发职员社区参与者。

接下来发作什么?

下一次 TC39 集会将于本周举办。议程中有一项议论 flatten 及其收集兼容性题目。愿望在集会完毕后我们会更多地相识下一步。

    原文作者:justjavac
    原文地址: https://segmentfault.com/a/1190000013855516
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞