因此,从根本上说,这个问题不是基于观点的.我认真地客观地研究这个问题,没有feeling个主要来自predominant opinion-Why is extending native objects a bad practice?

这个问题是相关但尚未回答的问题:

If Object.prototype is extended with Symbol property, is it possible to break code without specifically designed APIs to access Symbol in JavaScript?

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

第一个问题已经结束了,因为他们说这是基于观点的,你可能知道,在这个社区,一旦一个问题被禁止,不管我们如何修改它,版主永远不会费心重新打开.这就是这里的工作方式.

关于第二个问题.由于一些未知的原因,这个问题被更加严肃地对待,虽然背景相同,但并不被认为是基于观点的.

"不要修改你不拥有的东西"规则分为两部分:

  1. 您可能会导致名称冲突,也可能会 destruct 它们的代码.

    通过touch 你不拥有的东西,你可能会意外地覆盖它

  2. 你可以创建紧密的依赖关系,它们会 destruct 你的代码.

    通过将代码与其他对象紧密绑定,如果它们

使用符号可以避免#1,但仍然会遇到#2.这样的类之间的紧密依赖通常是不被鼓励的.如果另一个类的值为frozen,那么代码仍然会中断.question上的answers仍然适用,只是原因略有不同.

此外,我也读过意见书(如果没有"意见"基础,我们怎么能在这里讨论这样的事情?),他们声称

a) 存在使用符号的库代码,它们可能会调整符号API(例如Object.getOwnPropertySymbols())

b) 用符号扩展对象属性与非符号属性没有本质区别.

在这里,因为非接触Object.prototype的主要理由是因为#1,我看到的几乎所有答案都声称这一点,我们不必讨论是否存在符号用法.

然而,正如他们所说,使用符号将避免#1.因此,大多数传统智慧将不再适用.

然后,正如#2所说,

通过将代码与其他对象紧密绑定,如果它们进行了一些重大更改(例如删除或重命名类),代码可能会突然中断.

原则上,任何基本的API版本升级都会 destruct 任何代码.众所周知的事实与这个具体问题无关#2没有回答这个问题.

剩下的问题只有相当一部分是Object.freeze(Object.prototype).然而,这本质上与其他人升级基本API的方式相同.

由于API用户不是API提供者,预期的API为Object.prototypenot frozen.

如果其他人触动了基本的API并将其修改为冻结,则是他/她 destruct 了代码.他们在没有通知的情况下升级了基本API.

例如,在Haskell中,有许多语言扩展.他们可能很好地解决了冲突问题,最重要的是,他们不会"冻结"基本API,因为冻结基本API会阻止他们的eco.

因此,我观察到Object.freeze(Object.prototype)是反模式.不能理所当然地阻止Object.prototype用符号扩展.

这是我的问题.尽管我这样观察,但可以安全地说:

如果没有执行Object.freeze(Object.prototype),这是反模式和可检测的,那么使用符号执行扩展Object.prototype是安全的吗?

如果你不这么认为,请提供一个具体的例子.

推荐答案

安全吗?是的,如果你意识到它带来的所有危险,或者 Select 忽略它们,对它们不屑一顾,或者投入精力确保它们不会发生(测试、明确的兼容性要求文档),那么它是安全的.在你自己的代码中,你可以自由地做这件事,你可以保证这些事情.

这是个好主意吗?仍然没有.不要在其他人将(必须)使用的代码中引入这一点.

如果其他人触动了基本的API并将其修改为冻结,则是他/她 destruct 了代码.因此,我观察到Object.freeze(Object.prototype)是反模式.

不完全是.如果你们都做了一些不该做的事情,你们都应该受到责备——即使只做其中一件事就可以通过运行代码逃脱惩罚.这正是#2的要点:不要将代码与其他人共享的全局对象紧密耦合.

然而,这些东西之间的区别是,one bit8572">freezing the prototype对prototype pollution attacksestablished practiceharden an application,通常效果很好(one bit除外),

在Haskell中,有许多语言扩展.他们可能很好地解决了冲突问题,最重要的是,他们不会"冻结"基本API,因为冻结基本API会阻止他们的eco.

Haskell没有任何全局的、共享的、可变的对象,所以整个问题有点不同.唯一的冲突问题是来自"star imported"模块的标识符之间的冲突,包括来自base API的前奏.然而,这是每个模块,而不是全局的,因此它不会 destruct 可组合性,因为您可以将相同的标识符解析为不同模块中的不同函数.

同样是的,他们的base API是冻结的and versioned,因此他们可以在不 destruct 旧应用程序的情况下对其进行改进(他们可以继续使用旧的依赖项和旧的编译器).这是JavaScript所没有的奢侈.

pipe符号扩展Object.prototype是否安全,这样something[pipe](f)就可以表示f(something),比如F#中的something |> f或管道运营商之前的提议?

不,这不安全,不适用于任意值something.一些显然不起作用的值是nullundefined.

然而,它甚至不适用于所有对象:有些对象的原型链上没有Object.prototype.一个例子是Object.create(null)(也是done for security purposes),另一个例子是来自其他领域的对象(例如iFrame).这也是原因.

因此,对于管道操作符,最好使用静态独立方法,或者只使用transpiler来获取实际需要的语法.Object.prototype方法只是一个糟糕的近似值.

Javascript相关问答推荐

在Phaser中查找哪个物体处于碰撞中

自定义帖子类型帖子未显示在网站上

具有相同参数的JS类

Chart.js V4切换图表中的每个条,同时每个条下有不同的标签.怎么做?

Chrome是否忽略WebAuthentication userVerification设置?""

将2D数组转换为图形

如何为我的astro页面中的相同组件自动创建不同的内容?

在我的html表单中的用户输入没有被传送到我的google表单中

如何在模块层面提供服务?

我在Django中的视图中遇到多值键错误

Webpack在导入前混淆文件名

当用户点击保存按钮时,如何实现任务的更改?

当我在Reaction中创建一个输入列表时,我的输入行为异常

邮箱密码重置链接不适用于已部署的React应用程序

expo 联系人:如果联系人的状态被拒绝,则请求访问联系人的权限

删除元素属性或样式属性的首选方法

当我点击一个按钮后按回车键时,如何阻止它再次被点击

在Vercel中部署Next.js项目时获取`ReferenceError:未定义文档`

为什么NULL不能在构造函数的.Prototype中工作

在HTML5画布上下文中使用putImageData时,重载解析失败