是否也应避免通过符号扩展内置 Javascript 原型?

Should the extension of built-in Javascript prototypes through symbols also be avoided?

predominant opinion 内置 Javascript 原型不应扩展(或以任何方式更改):

Array.prototype.empty = function () { return this.length === 0; } // don't try that

这条规则是否也适用于 ES2015 符号?

const empty = Symbol("empty");
Array.prototype[empty] = function empty() { return this.length === 0; }

由于 symbolstring(原始的,不可变的)和 object(身份)的混合体,因此根据定义不存在对象 属性 命名冲突。

普通物体反射不受符号影响:

Object.getOwnPropertyNames(Array.prototype).indexOf("empty"); // -1

但是 Reflect.ownKeys(Array.prototype) 的 ES2015 反射是。

所以这个问题主要是关于我们以后如何使用Reflect.ownKeysObject.getOwnPropertySymbols

是的。

“不要修改你不拥有的东西”规则有两个部分:

  1. 您可能会导致名称冲突,并且 可能会破坏 他们的 代码。

    通过触摸不属于您的内容,您可能会不小心覆盖其他图书馆使用的内容。这将以意想不到的方式破坏他们的代码。

  2. 您可以创建紧密的依赖关系,并且 它们 可以破坏 您的 代码。

    通过将您的代码与其他对象如此紧密地绑定在一起,如果它们进行了一些重大更改(例如删除或重命名 class),您的代码可能会突然崩溃。

使用符号将避免#1,但您仍然运行进入#2。 class 之间的紧密依赖通常是不鼓励的。如果另一个 class 曾经 frozen, your code will still break. The answers on this question 仍然适用,只是原因略有不同。

您想专注于 loosely binding 您的依赖项以支持更好的测试(松散的绑定更容易模拟)和更容易的维护(一些明显的连接更容易记录和更新)。

明确一点:名称冲突只是 tightly-bound 依赖项引起的问题的一个症状。