web-dev-qa-db-ja.com

Object.prototype JavaScriptの拡張

私はこれが大丈夫かどうか尋ねていません:

_Object.prototype.method = function(){};
_

これはfor(var i in obj)を台無しにすることを考えると、ほとんどの人がevilと見なします。

本当の質問

無視する

  • 能力のないブラウザ(_Object.defineProperty_をサポートしないブラウザ)
  • プロパティの衝突またはオーバーライドの可能性

あなたがいくつかの信じられないほど有用な方法を持っていると仮定すると、これは間違っている/非倫理的と見なされますか?

_Object.defineProperty(Object.prototype, 'methodOnSteriods',{
  value: function(){ /* Makes breakfast, solves world peace, takes out trash */ },
  writable: true,
  configurable: true,
  enumerable: false
});
_

上記が非倫理的であると思われる場合、なぜ最初から機能を実装しているのでしょうか?

35
Lime

ターゲット環境で動作するようであれば問題ないと思います。

また、プロトタイプ拡張の偏執狂は誇張されていると思います。良い開発者のようにhasOwnProperty()を使用している限り、問題はありません。最悪の場合、そのプロパティを他の場所でオーバーロードし、メソッドを失います。しかし、そうするのはあなた自身の責任です。

24
Alex Wayne

これは前と同じようにalmost悪だと思います。最大の問題は、以前と同じですが、Object.prototypeがグローバルであることです。あなたの方法は現在世界平和を解決しているかもしれませんが、他の誰かの方法(銀河の平和を保証していた)を上書きしたり、あなたが制御できないいくつかのライブラリによって将来上書きされたりするかもしれません(したがって、世界を再び混乱に陥れます)


Javascriptの新しいバージョンには、プロパティを列挙可能/列挙不可に定義したり、ゲッターやセッターを設定したりするなど、プロパティに関連する多くの機能があります。Object.definePropertyは、これを制御するために存在します。

Mozilla Docs から:

このメソッドを使用すると、オブジェクトのプロパティを正確に追加または変更できます。割り当てによる通常のプロパティの追加は、プロパティの列挙(for ... inループ)中に表示されるプロパティを作成し、その値は変更される可能性があり、削除される可能性があります。この方法では、これらの追加の詳細をデフォルトから変更できます。


この新機能は基本的に新機能をサポートするために必要であり、あなた自身のものでそれを使用することになっています。 Object.prototypeを変更できることは、「通常の」オブジェクトであることの副作用にすぎず、以前と同じように悪です。

11
hugomg

「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;
    }
}
3
sacabuche

.hasOwnProperty()は、継承されたプロパティによる反復を除外します。これは、私が個人的に役立つよりも煩わしい場合が多いことを発見しました。これはObject.create()の有用性を大きく損ないます。これは皮肉なことですが、.hasOwnProperty()を実行するように説得したのと同じ人がObject.create()も宣伝したためです。

ここにリストされている理由により、Object.prototypeは拡張しないでください。本当に拡張したい場合は、拡張機能を非反復可能にします。

これは、公開されているすべてのベストプラクティスに直面していることに気づきますが、オブジェクトキーの反復に対する「必須」.hasOwnProperty()を停止し、オブジェクト間の直接継承の有用性を受け入れる必要があります。

3
Nomad128

短い答えははい、あなたはそれをすべきです。

それを行う前に、いくつかの予防策を講じる必要があります。
1。オブジェクトを反復するときにhasOwnPropertyを使用しますが、これは実際には予防策ではありません。オブジェクトを反復するときは、とにかくhasOwnPropertyをすでに使用しています。
2。 _Object.prototype.name_のnameが存在するかどうかを確認してください。これは、名前の衝突を避けるために非常に安全です。
3。 Object.defineProperty()を利用して、追加の保護層を追加します。

ご覧のとおり、それほど複雑ではありません。

リスク/デメリットに対処すると、次のようなメリットがあります。
1。メソッドチェーニング。これにより、コードが読みやすく簡潔になり、コーディングがより楽しくなります。順番にあなたが幸せになり、あなたの人生が容易になります。
2。ブラウザの互換性の問題を解決します。とにかくポリフィルを実行しています。

追伸:
大規模なチームで作業する場合は、絶対に行わないでください。

0
alexcres