扩展 Object.prototype JavaScript

发布于 2024-11-26 22:11:35 字数 551 浏览 2 评论 0原文

我不是在问这是否可以:

Object.prototype.method = function(){};

几乎每个人都认为这是邪恶,因为它搞乱了for(var i in obj)

真正的问题

忽略

  • 不合格的浏览器(不支持Object.defineProperty的浏览器)
  • 属性冲突或覆盖的可能性

假设您有一些令人难以置信有用的方法,这被认为是错误的/不道德?

Object.defineProperty(Object.prototype, 'methodOnSteriods',{
  value: function(){ /* */ },
  writable: true,
  configurable: true,
  enumerable: false
});

如果您认为上述内容是不道德的,那么他们为什么要首先实现该功能呢?

I am not asking if this is okay:

Object.prototype.method = function(){};

This is deemed evil by pretty much everyone, considering it messes up for(var i in obj).

The Real Question

Ignoring

  • Incompetent browsers(browsers that don't support Object.defineProperty)
  • Potential for property collision or overriding

Assuming you have some incredibly useful method, is this considered wrong/unethical?

Object.defineProperty(Object.prototype, 'methodOnSteriods',{
  value: function(){ /* */ },
  writable: true,
  configurable: true,
  enumerable: false
});

If you believe the above is unethical, why would they even implement the feature in the first place?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

稚气少女 2024-12-03 22:11:35

2021 年更新

尽管这是公认的答案,但 10 年的经验告诉我这不是最好的主意。几乎任何可以避免污染全局范围的事情都是一件非常非常好的事情。

下面的原始答案,为了后代,并且因为堆栈溢出不会让我删除已接受的答案。


2011 年的原始答案

我认为如果它在你的目标环境中工作就很好。

我还认为原型扩展偏执被夸大了。只要您像优秀的开发人员一样使用 hasOwnProperty() 就可以了。最坏的情况是,您在其他地方重载该属性并丢失该方法。但如果你这样做了,那是你自己的错。

UPDATE from 2021

Despite this being the accepted answer, 10 years of experience has taught me this isn't the best idea. Pretty much anything you can do to avoid polluting the global scope is a very very good thing.

Original answer below, for posterity, and because stack overflow will not let me delete an accepted answer.


Original answer from 2011

I think it's fine if it works in your target environment.

Also I think prototype extension paranoia is overblown. As long as you use hasOwnProperty() like a good developer that it's all fine. Worst case, you overload that property elsewhere and lose the method. But that's your own fault if you do that.

少女净妖师 2024-12-03 22:11:35

我想说这几乎和以前一样邪恶。最大的问题仍然和以前一样,是Object.prototype 是全局的。虽然你的方法目前可能正在解决世界和平问题,但它可能会覆盖别人的方法(保证银河和平),或者将来可能会被你无法控制的某个库覆盖(因此世界再次陷入混乱)


新版本Javascript 有很多与属性相关的功能,例如定义可枚举/不可枚举的属性、具有 getter 和 setter...Object.defineProperty 的存在就是为了对此进行控制。

来自 Mozilla 文档

此方法允许精确添加或修改属性
在一个物体上。通过分配创建的正常属性添加
在属性枚举期间显示的属性(for...in 循环),
其值可以更改,并且可以删除。这个方法
允许更改这些额外详细信息的默认值。


这个新功能基本上需要支持新功能,并且您应该在自己的东西上使用它。能够修改 Object.prototype 只是它作为“普通”对象的副作用,并且和以前一样邪恶。

I'd say this is almost as evil as before. The biggest problem, still the same as before, is that Object.prototype is global. While your method might currently be solving world peace, it might have overwriten someone else's method (that was guaranteeing galactic peace) or may be overwritten in the future by some library you have no control over (therefore plunging the world into chaos again)


New versions of Javascript have lots of features related to properties, such as definig a property to be enumerable/not enumerable, having getters and setters... Object.defineProperty existis to give control over this.

From Mozilla Docs:

This method allows precise addition to or modification of a property
on an object. Normal property addition through assignment creates
properties which show up during property enumeration (for...in loop),
whose values may be changed, and which may be deleted. This method
allows these extra details to be changed from their defaults.


This new function is basically required to support the new features and you are supposed to use it on your own stuff. Being able to modify Object.prototype is just a side effect of it also being a "normal" object and is just as evil as before.

活雷疯 2024-12-03 22:11:35

在“JavaScript:好的部分”中,有一个类似的函数,我认为这对于改进 javascript 基本对象(如 String、Date 等)非常有用,但仅此而已。

// Add a method conditionally. from "JavaScript: the good parts"

Function.prototype.method = function (name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
    }
}

Well in "JavaScript: the good parts", there is a similar function, i think that is very usefull to improve javascript base objects (like String, Date, etc..), but just for that.

// Add a method conditionally. from "JavaScript: the good parts"

Function.prototype.method = function (name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
    }
}
樱桃奶球 2024-12-03 22:11:35

.hasOwnProperty() 将排除通过继承属性进行的迭代,我个人认为这通常更烦人而不是有用。它在很大程度上削弱了 Object.create() 的实用性——这很讽刺,因为说服每个人都这样做 .hasOwnProperty() 的同一个人也推广了 Object.create ()

由于此处列出的原因,不应扩展 Object.prototype。如果您确实想扩展它,请使扩展不可迭代。

我意识到这与所有已发布的最佳实践背道而驰,但我们确实应该停止在对象键迭代上“强制”.hasOwnProperty(),并拥抱直接对象到对象的有用性遗产。

.hasOwnProperty() will exclude iteration through inherited properties, which I personally find is often more annoying than helpful. It largely defeats the usefulness of Object.create()—which is ironic since the same guy who convinced everyone to do .hasOwnProperty() also promoted Object.create().

Object.prototype should not be extended, for the reasons listed here. If you really do want to extend it, then make the extensions non-iterable.

I realize this flies in the face of all of the published best-practices, but we really should stop “mandating” .hasOwnProperty() on object key iterations and embrace the usefulness of direct object-to-object inheritance.

贵在坚持 2024-12-03 22:11:35

简短的回答是,是的,你应该这样做。

在此之前,需要采取一些预防措施:
1. 在迭代对象时使用 hasOwnProperty ,但这并不是真正的预防措施,在迭代对象时,我已经在使用 hasOwnProperty 了。
2. 检查Object.prototype.name中的name是否存在,这样可以非常安全地避免名称冲突。
3.利用Object.defineProperty(),只需添加额外的保护层即可。

正如您所看到的,它并不是很复杂。

一旦您考虑了风险/缺点,现在就会出现优点:
1.方法链接,这只会让代码更可读、更简洁,让编码变得更愉快。反过来,你会更快乐,你的生活也会更轻松。
2.解决浏览器兼容性问题,反正你是在做polyfill。

PS:
与大型团队合作时,绝对不要这样做。

The short answer is Yes, you should do it.

Before doing it, there are several precautions need to take:
1. using hasOwnProperty when iterating object, but this isn't really a precautions, when iterating object, I am already using hasOwnProperty anyway.
2. check if the name in Object.prototype.name has existed, this is very safe to avoid name collision.
3. take advantage of Object.defineProperty(), just add extra safeguard layer.

As you can see, it's not very complicated.

Now comes the advantages once you have taken care of the risks/disadvantages:
1. method chaining, this just makes code more readable, terse, and making coding more enjoyable. In turn makes you happier, and your life easier.
2. solves the browser compatibility issue, you are doing polyfill anyway.

P.S.:
Don't do it when working with a large team for sure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文