いつバニラJavaScriptとjQueryを使用するのですか?


238

私は実際にすることができますことを、代わりにjQueryのは、JavaScriptを使用して、特定の慣行があることを、一般的なjQueryの質問に答えるためにしようと/監視しながら気づいたあまり書いてください ...よく同じ量を。また、パフォーマンス上の利点も得られます。

具体的な例

$(this)this

クリックされたオブジェクトIDを参照するクリックイベント内

jQuery

$(this).attr("id");

Javascript

this.id;

このような他の一般的な方法はありますか?jQueryを混在させることなく、特定のJavaScript操作を簡単に実行できる場合。それともまれなケースですか?(実際にはより多くのコードが必要なjQueryの「ショートカット」)

編集:私はjQueryとプレーンJavaScriptのパフォーマンスに関する答えを高く評価していますが、実際にはもっと定量的な答えを探しています。 jQueryを使用しているときに、実際にを使用する代わりにプレーンJavaScriptを使用するほうがよい(読みやすさ/コンパクトさ)場合$()。元の質問で挙げた例に加えて。


質問が理解できるかわかりません。ライブラリコードを使用するメリットについての意見を探していましたか、それとも、jQuery以外のブラウザーに対応していない、互換性のある追加のテクニックを探していましたthis.idか?
user113716 2011年

1
私が概説したような一般的な(不正な)プラクティスのインスタンスのリストをほぼまとめるために、私はそれを非常に定量的であるように意図したので、答えから、誰もがこの質問を哲学的であると見なしているようです。
jondavidjohn


回答:


207
  • this.id (あなたが知っているように)
  • this.value(ほとんどの入力タイプで、私が知っている唯一の問題は、要素にプロパティが設定され<select>ていない場合のIE か、Safariのラジオ入力です。)value<option>
  • this.className 「クラス」プロパティ全体を取得または設定するには
  • this.selectedIndexに対して<select>選択されたインデックスを取得する
  • this.options反対<select>のリストを取得するための<option>要素を
  • this.text<option>テキストコンテンツを取得することに対して
  • this.rows反対<table>のコレクションを取得するための<tr>要素を
  • this.cells<tr>そのセルを取得するaに対して(td&th)
  • this.parentNode 直接の親を取得する
  • this.checkedThanks @Tim Downのチェック状態を取得するにはcheckbox
  • this.selected感謝の選択状態を取得するにはoption @Tim Down
  • this.disabledありがとう@Tim Downの無効状態を取得するにはinput
  • this.readOnlyThanks @Tim Downの readOnly状態を取得するinput
  • this.href<a>取得する要素に対してhref
  • this.hostname<a>のドメインを取得する要素に対してhref
  • this.pathname<a>のパスを取得する要素に対してhref
  • this.search<a>要素に対してクエリ文字列を取得するhref
  • this.src を持つことが有効な要素に対して src

...あなたはアイデアを理解していると思います。

パフォーマンスが重要になる場合があります。ループで何かを何度も実行している場合のように、jQueryを破棄したい場合があります。

一般的に、次のものを置き換えることができます。

$(el).attr('someName');

と:

上記の言葉遣いは不十分でした。getAttribute置換ではありませんが、サーバーから送信された属性の値を取得し、対応setAttributeする属性が設定します。場合によっては必要です。

以下の文章はそれをカバーしている。より良い治療法については、この回答参照してください

el.getAttribute('someName');

...属性に直接アクセスするため。属性はプロパティと同じではないことに注意してください(ただし、それらは相互にミラーリングする場合があります)。もちろんありsetAttributeます。

特定のタイプのすべてのタグをアンラップする必要があるページを受け取ったとしましょう。jQueryを使用すると、短くて簡単です。

$('span').unwrap();  // unwrap all span elements

しかし、多数ある場合は、少しネイティブなDOM APIを実行することをお勧めします。

var spans = document.getElementsByTagName('span');

while( spans[0] ) {
    var parent = spans[0].parentNode;
    while( spans[0].firstChild ) {
        parent.insertBefore( spans[0].firstChild, spans[0]);
    }
    parent.removeChild( spans[0] );
}

このコードはかなり短く、jQueryバージョンよりもパフォーマンスが高く、個人用ライブラリで再利用可能な関数に簡単に変更できます。

whileせいでwhile(spans[0])、外側に無限ループがあるように見えるかもしれませんが、「ライブリスト」を扱っているため、を実行すると更新されparent.removeChild(span[0]);ます。これはかなり気の利いた機能であり、代わりに配列(または配列のようなオブジェクト)を操作するときに見逃しています。


2
nice ...なので、主にthisキーワードを中心に展開され、不必要にjQueryオブジェクトにラップされています。
jondavidjohn

1
@jondavidjohn:さて、いくつかの場合にいくつかのthis.valueブラウザの癖があるように、いくつかの場合に良いいくつかの修正があります。それはすべてあなたの必要性に依存します。特にパフォーマンスが重要な場合は、jQueryがなくても簡単に使える素晴らしいテクニックがたくさんあります。もっと考えてみます。
user113716 2011年

3
答えを書こうとしましたが、代わりにあなたの提案を追加します。一般的に、attr()過度に使用されています。1つの要素のみを扱う場合は、ほとんど必要ありませんattr()。私のお気に入りの二つは、周りに混乱しているchecked:チェックボックス(その1つの周りに神秘的な呪文のあらゆる種類の財産$(this).attr("checked", "checked")$(this).is(":checked")同様など)selectedのプロパティ<option>要素。
Tim Down

1
Aaargh、@ patrick、noooo:お勧めしましたgetAttribute()ほとんど必要ありません。IEでは壊れており、常に現在の状態を反映しているわけではなく、いずれにしてもjQueryが行うことではありません。プロパティを使用するだけです。stackoverflow.com/questions/4456231/…–
Tim Down

1
私は長い間JSを使用しており、classNameについては知りませんでした。
IAdapter

60

正解は、「プレーンな」ネイティブJavaScriptの代わりにjQueryを使用すると、常にパフォーマンスが低下するということです。これは、jQueryがJavaScriptライブラリであるためです。JavaScriptの豪華な新しいバージョンではありません。

jQueryが強力である理由は、ブラウザー間で非常に退屈な作業(AJAXは最良の例の1つです)を実行し、無数の使用可能なブラウザー間の不整合を解消し、一貫したAPIを提供するためです。また、要素のグループでの作業を単純化するために、チェーン、暗黙の反復などの概念を容易に促進します。

jQueryの学習は、JavaScriptの学習に代わるものではありません。前者を知っていることで簡単にできることを十分に理解できるように、後者にはしっかりとした根拠が必要です。

-コメントを含むように編集-

コメントはすぐに指摘できるので(私は100%同意します)、上記のステートメントはベンチマークコードを参照しています。「ネイティブ」JavaScriptソリューション(適切に記述されている場合)は、ほとんどすべての場合に同じことを実行するjQueryソリューションよりも優れています(そうでない場合は、例を参照してください)。jQueryは開発時間を短縮します。これは、私が軽視するつもりはない大きな利点です。読みやすく、コードを簡単に追跡できるので、一部の開発者は自分で作成することができません。

私の意見では、答えはあなたが達成しようとしていることに依存します。パフォーマンス上の利点への言及に基づいて推測したように、アプリケーションの可能な限り最高の速度を求めている場合、jQueryを使用すると、呼び出しのたびにオーバーヘッドが発生します$()。可読性、一貫性、ブラウザ間の互換性などを求めている場合は、「ネイティブ」JavaScriptよりもjQueryを優先する理由が確かにあります。


8
jQueryが純粋なJSでの実装よりも優れている状況の例をぜひご覧ください。何をするにせよ、jQuery(またはそのための他のライブラリ)を使用している場合は、避けられない関数オーバーヘッドがあります。を呼び出すことによって生成される(とはいえ)わずかなオーバーヘッドを回避する方法はありません$()。その呼び出しを行わない場合は、時間を節約できます。
gddc 2011年

16
不十分に書かれた自家製のソリューションはおそらく遅くなるでしょう。jQueryチームは、パッケージで非常に効率的なJavaScriptを実行しました。@Freelancerの回答を参照してください。
Stephen

3
不十分に書かれたソリューションは常に不十分に書かれたソリューションであり、それは言語のせいではありません。ライブラリがオーバーヘッドを被るという事実は変わりません。よく考えた場合、「ネイティブ」関数が回避できるオーバーヘッドが発生します。
gddc 2011年

11
@gddc jQueryが(ベンチマークボックスの外側を読んだ)純粋なJSが開発時間を短縮し(ビジネス的には莫大な価値です)、実験を簡略化する最良の例だと思います
Ben

13
あなたが書いたものはすべて真実ですが、@ Benが上記でメモしたことは省略しています。jQueryは、開発者をより速く、より堅牢にします。私が何年も前に書いて頻繁に使用したこのKillClass()実装を参照してください。あのね?それはだ壊れ特定のエッジケースのために。貧弱なコードは貧弱なコードであり、間違ったコードは間違ったコードですが、jQueryを使用すると、開発者は多くの場合、より優れた正しいコードを作成できます。ほとんどの場合、コンピュータは十分高速です。助けが必要なのは開発者です。
Phrogz

38

と呼ばれるフレームワークがあります...ああ、何だと思いますか?Vanilla JS。冗談を言ってくれるといいのですが...:Dパフォーマンスのためにコードの読みやすさを犠牲にしています...以下と比較するとjQueryDOM要素の取得IDがほぼ35倍高速であることがわかります。:)

したがって、パフォーマンスが必要な場合は、Vanilla JSを試して、独自の結論を導き出してください。forループ内などの集中的なコードの実行中に、JavaScriptがブラウザのGUIをハングさせたり、UIスレッドをロックしたりすることはないでしょう。

Vanilla JSは、信じられないほど強力なJavaScriptアプリケーションを構築するための高速、軽量、クロスプラットフォームのフレームワークです。

彼らのホームページにはいくつかの性能比較があります:

ここに画像の説明を入力してください


1
@Leniel Macaferi Oh Man私はこの答えが大好きでした!バニラと他のフレームワークとの間のパフォーマンスがそのような違いをもたらすことができることを私は知りませんでした!とにかくこの答えの名誉の殿堂!! PS:あなたもウェブサイトを作りましたか?
スティーブ

17

すでに受け入れられた回答がありますが、実際にクロスブラウザーのサポートが保証されているネイティブJavaScriptメソッド/属性のリストで、ここに直接入力した回答は包括的ではないと思います。そのため、quirksmodeにリダイレクトします。

http://www.quirksmode.org/compatibility.html

これはおそらく、どこでどのブラウザで機能するか、機能しないかについての最も包括的なリストです。DOMセクションに特に注意してください。読むのは大変ですが、すべて読むのではなく、参考にしてください。

私が真剣にWebアプリを書き始めたとき、私はすべてのDOMテーブルを印刷して壁に掛けました。これにより、何を安全に使用でき、何がハックを必要とするかが一目でわかります。最近quirksmode parentNode compatibility、私は疑わしいときのようにググるだけです。

他のように、判断はほとんど経験の問題です。サイト全体を読み、すべての問題を覚えてjQueryをいつ使用し、いつプレーンJSをいつ使用するかを理解することはお勧めしません。リストに注意してください。検索は簡単です。時間の経過とともに、いつプレーンなJSが望ましいかという本能を発達させるでしょう。


PS:PPK(サイトの作者)にも非常に良い本があり、私は読むことをお勧めします


14

いつ:

  1. あなたはあなたがしていることのためのクロスブラウザサポートを提供しています。
  2. 入力するコードが大幅に増えるわけではありません。
  3. 可読性が大幅に低下するわけではなく、
  4. jQueryがブラウザーに基づいて異なる実装を選択しないことで、パフォーマンスが向上することを確信しています。

JavaScriptを使用します。それ以外の場合は、jQueryを使用します(可能な場合)。

編集:この答えは、jQuery全体を使用することを選択する場合と、除外しない場合、およびjQuery内でバニラJSを使用するかどうかを選択する場合の両方に適用されます。間の選択attr('id').idの間で選択しながら、JSの賛成で傾くremoveClass('foo').className = .className.replace( new Regexp("(?:^|\\s+)"+foo+"(?:\\s+|$)",'g'), '' )のjQueryの賛成で傾きます。


3
OPはjQueryを使用するつもりだと思いますが、彼のjQueryメソッド内でネイティブJavaScriptをいつどこで使用するのか疑問に思います。
Stephen

.classList.remove('foo')新しいブラウザでは問題なく動作するようです
Tyilo

3
@Tyilo classList.removeは、IE9に実装されていないHTML5 ClassList APIの一部です。たとえば、caniuse.com

13

他の回答は、「jQuery対プレーンJS」の幅広い質問に焦点を当てています。OPから判断すると、jQueryを使用することを既に選択している場合は、バニラJSを使用するほうがよい場合は単に疑問に思っていたと思います。あなたの例はあなたがバニラJSを使うべきときの完璧な例です:

$(this).attr('id');

次の場合よりも遅くなり、(私の意見では)読みにくくなります:

this.id

jQueryで属性を取得するためだけに新しいJSオブジェクトを起動する必要があるため、処理速度は遅くなります。ここで、$(this)他の操作を実行するために使用する場合は、必ず、そのjQueryオブジェクトを変数に格納して操作してください。ただし、要素の属性(idまたはsrc)だけが必要な多くの状況に遭遇しました。

このような他の一般的な方法はありますか?jQueryを混在させることなく、特定のJavaScript操作を簡単に実行できる場合。それともまれなケースですか?(実際にはより多くのコードが必要なjQueryの「ショートカット」)

最も一般的なケースはあなたがあなたの投稿で説明したものだと思います。$(this)jQueryオブジェクトを不必要にラッピングする人々。私はこれidvalue(およびの代わりに$(this).val())で最も頻繁に見ています。

編集: ケースでjQueryの使用が遅い理由を説明する記事を次に示します。告白:タグwikiから盗んだが、質問について言及する価値があると思う。attr()

もう一度編集します。属性に直接アクセスするだけの読みやすさ/パフォーマンスの影響を考えると、this.<attributename>可能な場合は使用することをお勧めします。ブラウザーの不整合が原因でこれが機能しない場合もあるでしょうが、機能しない場合は最初に試してjQueryにフォールバックすることをお勧めします。


ええと、質問を読んでくれてありがとう;)...これはより広い例外です?
jondavidjohn、2011年

@jondavidjohn:正直なところ、私はその電話をかけるのをためらっています。そうだと思います。クロスブラウザの懸念があるため、jQueryを使用することは通常あなたにとって有利です。のような他の例がありますthis.style.display = 'none'。それより良いです$(this).hide()か?後者の方が読みやすいと思いますが、前者の方が速いと思われます。jQueryを使用せずに特定のアクションがブラウザー間で機能するかどうかを確認するために実験を行っても問題はありません。これは通常、jQueryオブジェクトに要素をラップして操作を実行する前に行うことです。
Andrew Whitaker

10

主にパフォーマンスに関心がある場合、主な例は頭の釘を打つことです。不必要にまたは冗長にjQueryを呼び出すことは、パフォーマンスの低下の2番目の主な原因です(最初はDOMトラバーサルが不十分である)。

これは実際にあなたが探しているものの例ではありませが、私はこれを頻繁に目にするので、次のことに言及します。

// poor
$(this).animate({'opacity':'0'}, function() { $(this).remove(); });

// excellent
var element = $(this);
element.animate({'opacity':'0'}, function() { element.remove(); });

// poor
$('.something').load('url');
$('.something').show();

// excellent
var something = $('#container').children('p.something');
something.load('url').show();

興味深い... varのインスタンス化とアクションのこの分離は、実際に処理パフォーマンスの向上につながりますか?または、アクションを単独で実行できるようにします(
おそらく

1
確かにパフォーマンスの向上につながりますが、選択した要素を再利用する場合に限られます。したがって、最後のケースvar somethingでは、jQueryオブジェクトをキャッシュする必要はありませんでした(チェインを使用したため)。
Stephen

2
一方、同じ例を見てみましょう。$('.something')2回呼び出すことは、jQueryがDOMを2回トラバースして、そのセレクターを持つすべての要素を探す必要があることを意味します。
Stephen

2
最初の例の場合、キャッシュ$(this)によりjQuery関数の呼び出しが削減されます。これにより、ループシナリオで最大の利益が得られます。
Stephen

2
@Alnitakにelement等しいことに注意してください$(this)。複数の要素は含まれません。
スティーブン

8

JSとJQの間には確かに重複があることがわかりました。あなたが示したコードはその良い例です。率直に言って、JSよりもJQを使用する最大の理由は、単にブラウザの互換性にあることです。JSで何かを成し遂げることができたとしても、私はいつもJQに傾いています。


8
JQueryはJavaScriptであるため、オーバーラップがなかったのではないでしょうか。
サイモン、2011年

6

これは私の個人的な見解ですが、とにかくjQueryはJavaScriptであるため、理論的にはバニラJSよりもパフォーマンスが良くないと思います。

しかし、手書きのコードはjQueryほど効率的ではない可能性があるため、実際には手書きのJSよりもパフォーマンスが優れている可能性があります。

結論-小さなものではバニラJSを使用する傾向があり、JS集約型プロジェクトではホイールを再発明せずにjQueryを使用したいので、生産性も向上します。


1
ライブラリがバニラJSよりも優れている例はたくさんあります。JSの組み込みプロトタイプメソッドの多くは不適切に記述されています。
例による統計の学習2015

3

最初の回答のthisDOM要素としてのライブプロパティリストは非常に完全です。

他の人を知ることも興味深いかもしれません。

これがドキュメントの場合:

  • this.forms を取得する HTMLCollection現在のドキュメントフォームには、
  • this.anchors設定されているHTMLCollectionすべてのものを取得するには、HTMLAnchorElementsname
  • this.links取得するHTMLCollectionすべてのHTMLAnchorElementと秒href設定されいる、
  • this.images取得するHTMLCollectionすべてのをHTMLImageElement Sを
  • そして非推奨のアプレットでも同じ this.applets

で作業する場合document.formsdocument.forms[formNameOrId]そのように指定または識別されたフォームを取得します。

これがフォームの場合:

  • this[inputNameOrId] そのように指定または識別されたフィールドを取得する

これがフォームフィールドの場合:

  • this.type フィールドタイプを取得する

jQueryセレクターを学習する場合、既存のHTML要素のプロパティの学習をスキップすることがよくあります。


あなたが言及したプロパティはDOM Level 2 HTML仕様で定義され、広くサポートされています。document.embedsそして、document.pluginsも広く(DOM 0)サポートされています。HTML5仕様document.scriptsで定義された便利なコレクションでもあり、広くサポートされています(およびFirefox 9以降)。
Rob W

@Robwしたがって、リストは完全なものになり、間違いなく便利で高速です。ありがとう;)
lib3d 2013年

2

いつものように私はこのパーティーに遅れます。

私がjQueryを使用することに決めたのは、それほど魅力的な追加機能ではありませんでした。結局のところ、独自の関数を作成することを妨げるものはありません。

メモリリークを回避するためにDOMを変更するときに学ぶべき非常に多くのトリックがあったことは事実でした(私はIEについて話しています)。私にとってこれらすべての種類の問題を管理する1つの中心的なリソースを持ち、かつてないほどずっと優れたJSプログラマーである人々によって書かれました。

私はこの種のブラウザのサポート/抽象化の議論に当てはまると思います。

そしてもちろん、jQueryは、必要なときにストレートJSの使用を排除しません。2つはシームレスに連携しているように感じました。

もちろん、ブラウザーがjQueryでサポートされていない場合、またはローエンド環境(古い電話?)をサポートしている場合は、大きな.jsファイルが問題になる可能性があります。jQueryが小さなものであったことを覚えていますか?

ただし、通常、パフォーマンスの違いは問題になりません。それは十分に速くなければならない。ギガヘルツのCPUサイクルが毎秒無駄になるので、18か月ごとに2倍にパワーアップしない唯一の開発リソースであるコーダーのパフォーマンスにもっと関心があります。

それは私が現在アクセシビリティの問題を調査していることを言った、そして明らかに.innerHTMLはそれで少しノーノーです。もちろんjQueryは.innerHTMLに依存しているので、許可されているやや面倒なメソッドに依存するフレームワークを探しています。そして、そのようなフレームワークはjQueryよりも実行速度が遅いと想像できますが、十分に機能する限り、私は満足します。


2

ここに技術的ではない答えがあります-多くの仕事はjQueryのような特定のライブラリを許可しないかもしれません。

実際、実際、Googleはコードの中でjQueryを許可していません(Facebookが所有しているため、Reactもそうではありません)。インタビュアーが「申し訳ありませんが、jQueryを使用することはできません。 XYZ Corporationの承認済みリスト」。バニラJavaScriptは、いつでもどこでも絶対に機能し、この問題が発生することはありません。ライブラリに依存している場合は、速度と使いやすさが得られますが、普遍性が失われます。

また、インタビューについて言えば、もう1つの欠点は、コードクイズ中にJavaScriptの問題を解決するためにライブラリを使用する必要があると言うと、実際には問題を理解していないように見え、ひどく見えます。一方、生のバニラJavaScriptでそれを解決する場合は、実際に理解し、目の前で発生する問題のあらゆる部分を解決できることを示しています。


1

$(this) とは異なります thisます:

を使用$(this)することで、jQueryプロトタイプがオブジェクトに渡されていることを確認できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.