2016-07-15 13 views
0

要素を拡張することに関して多くの議論があります。私の知る限り、これらが主な問題は、次のとおりです。JavaScript:要素のプロトタイプを拡張する

  • それは他のライブラリ
  • と競合する可能性DOMはそれがレガシーIE
  • とそれを動作しません
  • ルーチンには文書化されていない機能が追加されています

    :未来と競合する可能性は他のライブラリ、ドキュメントの変更を参照していない、と歴史的なブラウザの気にしていないプロジェクトを考えると

を変更

要素のプロトタイプを拡張しない理由がありますか。技術ここでは、これは便利である方法の例です:

Element.prototype.toggleAttribute=function(attribute,value) { 
    if(value===undefined) value=true; 
    if(this.hasAttribute(attribute)) this.removeAttribute(attribute); 
    else this.addAttribute(attribute,value); 
}; 

私は合理的な説明を提供することなく、プロトタイプを拡張するの弊害について、あまりにも多くのコメントを見てきました。

注1:toggleAttributeは今後追加される可能性のある種類のものであるため、上記の例はあまりにも明白です。議論のために、それがmanngoToggleAttributeと呼ばれると想像してください。

注2:メソッドがすでに存在するかどうかのテストを削除しました。たとえそのようなメソッドが既に存在していても、それをオーバーライドする方がより予測可能です。いずれにせよ、ここでのポイントは、メソッドがまだ定義されておらず、実装されているのではなく、であると仮定しています。それがここのポイントです。

ありがとうございました

+3

将来の互換性に問題があるかもしれません。追加している機能が将来標準の一部になる可能性があります。 – Timo

+1

「技術的な理由」とまったく同じ意味ですか?いいえ、「要素」を拡張することは、あなたが把握したように、制御された環境でうまく動作します。 – Bergi

+0

@TimoStaテストを含めるようにコードサンプルを変更しました。 – Manngo

答えて

0

あなたが所有していないオブジェクトは変更しないでください。

将来の標準がElement.prototype.toggleAttributeと定義されているとします。あなたのコードはあなたの関数を割り当てる前に本当の値を持っているかどうかチェックします。だから、将来のネイティブ関数で終わる可能性があります。これは、期待したものとは異なる動作をする可能性があります。

さらに、Element.prototype.toggleAttributeを読むだけでゲッターが呼び出され、望ましくない横効果を伴うコードが実行される可能性があります。たとえば、Element.prototype.idを取得したときにどうなるかを参照してください。

チェックをスキップして、機能を直接割り当てることができます。しかし、それはいくつかの望ましくない横向きの影響でセッターを実行する可能性があり、あなたの関数はプロパティとして割り当てられません。

プロパティ割り当ての代わりにプロパティ定義を使用できます。それは安全でなければなりません... Element.prototypeにはいくつかの特殊な[[DefineOwnProperty]]内部メソッド(プロキシなど)がない限り。

多くの方法で失敗する可能性があります。これをしないでください。

+0

だからどうすればいいですか? –

+0

@BekimBacajもし何があったら? – Oriol

+0

Opsのコメントで件名に私の完全な返信を参照してください。 –

-1

Elementプロトタイプを拡張しないような技術的な理由はありますか?

絶対にありません!

恩赦: 絶対にありません!

さらに、 .__proto__は、実際には昨日までの不正なプロトタイプ拡張でした。 - 今日、それは基準です。


p.s:あなたは(Element.prototypeで「toggleAttribute」)が行います場合は、任意の手段によってif(!Element.prototype.toggleAttribute)構文の使用は避けるべきです。

+1

どのように確認できますか?何か情報源がありますか?何が前提条件、制限、それが壊れたときにコードが失敗するのでしょうか? – Bergi

+0

新しい「id」プロパティで「Element.prototype」を「拡張」してみてください。 'if(Element.prototype.id)'がスローされます。 'Element.prototype.id = 123'がスローされます。同様に、 'toggleAttribute'を追加することは、将来の保証ではありません。 – Oriol

+0

@Bergiはい私は持っています - JavaScriptアプリケーションの私の経験は、あなたの年齢を超え、おそらく延長します。そして、私はそれらの事のどれかを推測しませんでした。コード自体は失敗しません。 –

1

大丈夫ですか?技術的にはい。ネイティブAPIを拡張する必要がありますか?親指の規則としてはない。残念ながら答えはより複雑です。 EmberやAngularのような大きなフレームワークを作成している場合は、APIの利便性が向上すれば消費者がBenifitsを持つことができるので、そうすることをお勧めします。しかし、あなた自身のためにこれをやっているのであれば、親指のルールはノーです。

このようにすると、そのオブジェクトの信頼が不安定になることが考えられます。言い換えれば、ネイティブオブジェクトを追加、変更、変更することによって、他の誰か(あなたの将来の自己を含む)が期待するよく理解され、文書化された動作に従うことはもうありません。

このスタイルでは、気付かれない実装を隠します。 この新しい方法は何ですか?それは秘密のブラウザのものですか?どうしますか?Googleやマイクロソフトにこれを報告してもらえますか?。少し誇張されていますが、APIの真実は今や変わってきており、この1つのケースでは予期せぬことです。メンテナンスは、独自の関数またはラッパーオブジェクトを使用した場合にはそうではないような余分な考えと理解を必要とします。また、変更が難しくなります。

関連のポスト:Extending builtin natives. Evil or not?

の代わりに誰か他の人の(または標準)をマックしようとしているコードだけで独自のものを使用します。

function toggleAttribute(el, attribute, value) { 
    var _value = (value == null ? true : value; 
    if (el.hasAttribute(attribute)) { 
    el.removeAttribute(attribute); 
    } else { 
    el.addAttribute(attribute, _value); 
    } 
}; 

これで、安全で、可搬性があり、持ち運びができ、保守が容易になりました。他の開発者(あなたの将来の自己を含む)は、標準APIまたはJS APIに記載されていないこの魔法の方法がどこから来たのか、彼らの頭を混乱させることはありません。

+0

OPは、なぜ彼が 'Element'プロトタイプを拡張すべきではないかと尋ねました。彼はそれを拡張しない解決策を求めなかった。 – destoryer

+1

ああああ、私はとても残念だ、私は答えてはならない!ああこれはひどいです。気分最悪。私は数日前から眠れません:( – Sukima

+1

あなたはコメントしてはいけません。 – destoryer

関連する問題