当前位置: 首页 > 知识库问答 >
问题:

javascript - 修改原型prototype会有什么风险?

梁德馨
2024-06-27

曾经看到过修改prototype这种做法不好,本人实际使用感觉非常方便,有什么不好的?
例如:
要在所有的react组件或vue组件中,做数字的格式化,直接如下:

String.prototype.toNum = Number.prototype.toNum = function(s) {    }

就能在所有组件中的任何字段,方便的调用toNum方法了,无需每个组件引入方法

共有4个答案

孟海
2024-06-27

其实大部分的JavaScript库都在大量的使用。比如Vue
平常自己用也很好。非要说风险,那就是多人合作时,需要注意一些风险点。

考虑兼容性问题

不要去覆盖已有的函数,自定义的尽量把名字取的奇怪一点,避免未知的情况下覆盖了已有的函数,可以考虑加一些前缀。

// 假设这是一个已有的库代码function doSomethingWithArray(arr) {  for (let item of arr) {    // 基于原始的 Array.prototype.includes 方法进行操作    if (!arr.includes(item * 2)) {      // 执行一些操作    }  }}// 其他地方修改了 Array.prototype.includes 方法Array.prototype.includes = function (value, fromIndex) {  // 自定义的实现,与原始行为不同  return false;};let myArray = [1, 2, 3];doSomethingWithArray(myArray); // 由于原型修改,这里的行为可能不再符合预期

代码可读性问题

别人阅读你代码时候,很陌生的函数''.toNum(),会疑惑干什么用的。尽可能可能把注释写写全问题也不大。告诉人家这个是哪儿定义的做什么用的。

性能影响

某些情况下,会影响JavaScript引擎优化策略,导致性能下降。特别是添加prototype特别多或者数据量特别大的情况下。

谭成业
2024-06-27

我非常喜欢这样的写法,面向对象的高级用法,逻辑上很实用

孙风畔
2024-06-27

自己用当然感觉不错,但是如果需要跟人合作就很麻烦了。现代化软件开发几乎不可能一个人完成,都要大量使用第三方开源仓库。如果每个人都往原型上挂东西,每个人写法都不一样,A 跟 B 冲突,一单用了 A,全部跟 B 相关的都不能用,那就是一场灾难。

现实世界也是如此,每个看起来不太合理的规定背后,可能都是你没遇到过的惨痛经历。

空夕
2024-06-27

在JavaScript中修改内置对象的原型(如String.prototypeNumber.prototype等)确实可能带来一些风险,尽管在某些场景下它看起来非常方便。以下是修改原型时可能遇到的一些风险和问题:

  1. 命名冲突:如果你添加的方法与现有方法或未来可能会添加的方法同名,那么你的方法将会覆盖它们,这可能导致难以调试的问题。
  2. 不可预测性:当你修改原型时,你改变了所有实例的行为。这可能会导致在不知情的情况下影响其他代码段。特别是在大型项目或第三方库中,这种改变可能是灾难性的。
  3. 非标准性:修改内置对象的原型并不是ECMAScript标准所推荐的做法。这意味着它可能不会被所有环境或未来的JavaScript版本所支持。
  4. 测试困难:如果你修改了原型,那么测试你的代码可能会变得更加困难,因为你需要确保所有的代码(包括你的代码和任何依赖的代码)都与你的修改兼容。
  5. 性能问题:虽然这通常不是主要问题,但在某些情况下,修改原型可能会引入一些小的性能开销,因为每次访问一个方法时都需要进行额外的检查。
  6. 可读性:对于不熟悉你的代码的人来说,看到你在使用someString.toNum()这样的方法可能会感到困惑,因为他们可能不知道toNum是哪里来的。
  7. 扩展性:如果你希望在未来扩展你的toNum方法(例如,添加新的参数或行为),那么你可能会发现很难在不破坏现有代码的情况下进行这样的扩展。

对于你的例子,即希望在所有的React或Vue组件中方便地格式化数字,更好的做法可能是创建一个工具函数或模块,并在需要的地方导入它。例如:

// numFormatter.jsexport function formatNumber(num) {    // 你的格式化代码}// 在你的组件中import { formatNumber } from './numFormatter';// 使用const formattedNum = formatNumber(someNumber);

这种方法更加清晰、可预测,并且更容易测试和扩展。

 类似资料:
  • 本文向大家介绍深入学习JavaScript中的原型prototype,包括了深入学习JavaScript中的原型prototype的使用技巧和注意事项,需要的朋友参考一下 javascript 是一种 prototype based programming 的语言, 而与我们通常的 class based programming 有很大 的区别,我列举重要的几点如下: 1.函数是first cla

  • [[Prototype]] JavaScript 中的对象有一个内部属性,在语言规范中称为 [[Prototype]],它只是一个其他对象的引用。几乎所有的对象在被创建时,它的这个属性都被赋予了一个非 null 值。 注意: 我们马上就会看到,一个对象拥有一个空的 [[Prototype]] 链接是 可能 的,虽然这有些不寻常。 考虑下面的代码: var myObject = { a: 2

  • Axure RP 8支持与该功能的合作 - 团队项目。 此功能不仅有利于分布式团队,也有利于单个用户。 单个用户的好处是能够在正在进行的工作上创建版本。 与团队项目合作 在团队项目方案中,每个团队成员都在其计算机上拥有项目的副本。 该项目将与共享存储库同步。 此共享存储库已连接到团队的其他成员。 在一天的工作过程之后,每个团队成员将创建新元素,检出文件,并通常编辑项目。 Check Out是一个常

  • 原型模式是指在保持性能的同时创建重复对象。 这种类型的设计模式属于创建模式,因为此模式提供了创建对象的最佳方法之一。 此模式涉及实现原型接口,该接口告诉创建当前对象的克隆。 当直接创建对象成本高时使用此模式。 例如,在昂贵的数据库操作之后创建对象。 我们可以缓存对象,在下一个请求时返回其克隆,并在需要时更新数据库,从而减少数据库调用。 实现 (Implementation) 我们将创建一个抽象类S

  • 本文向大家介绍Javascript中的Prototype到底是什么,包括了Javascript中的Prototype到底是什么的使用技巧和注意事项,需要的朋友参考一下 Javascript也是面向对象的语言,但它是一种基于原型Prototype的语言,而不是基于类的语言。在Javascript中,类和对象看起来没有太多的区别。 什么是prototype: function定义的对象有一个proto

  • 修改superset前端文件,(superset-frontend文件夹下的文件)。npm run dev-server 和 superset run -p 8088前后端分别启动,访问前端链接,会发现对前端界面的修改是已经生效的。。。。。但是npm run -p 8088直接运行superset项目,访问对应的链接,发现前端的修改没有生效,(修改后,有重新打包前端项目,打包成功,在superse

  • 问题内容: 我对map()的行为感到困惑。 我有一个这样的对象数组: 我将此数组传递给应该返回相同数组但所有产品均免费的函数: 函数是: 它返回以下数组: 所以我重写了我的职能是: 它将按预期返回数组。 但是!在那一刻,我放松了主意,在这两种情况下,我都修改了原始产品阵列。 有关map()的文档说不应这样做(https://developer.mozilla.org/en- US/docs/Web

  • 问题内容: 在下面的视频中,Microsoft PDC演示者在时间标记21:40处说,包装所有JSON以使其不是顶级数组很重要: https://channel9.msdn.com/Events/PDC/PDC09/FT12 解开顶层阵列的风险是什么? 我应该如何检查并确定自己是否脆弱?我从第三方购买了许多组件,并且有外部厂商来开发我的代码。 问题答案: 微软之所以这样说,是因为他们尚未修补浏览器