web-dev-qa-db-ja.com

Vanilla JavaScriptとjQueryを使用する場合

監視/一般的なjQueryの質問への回答の試行中に、jQueryの代わりにjavascriptを使用する特定のプラクティスがあり、実際にwrite lessおよびdo...まあ同じ量。また、パフォーマンス上の利点も得られます。

具体的な例

$(this) vs this

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

jQuery

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

Javascript

this.id;

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

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

233
jondavidjohn
  • this.id(ご存じのとおり)
  • this.value(ほとんどの入力タイプ。<select><option>要素に設定されたvalueプロパティ、またはSafariのラジオ入力がない場合、IEのみが問題です。)
  • this.classNameは、「クラス」プロパティ全体を取得または設定します
  • this.selectedIndex<select>に対して選択して、選択したインデックスを取得します
  • this.options<select>に対して<option>要素のリストを取得する
  • this.text<option>に対してテキストコンテンツを取得する
  • this.rows<table>に対して<tr>要素のコレクションを取得する
  • this.cells<tr>に対して、セル(td&th)を取得する
  • this.parentNodeは直接の親を取得します
  • checkboxのチェック状態を取得するthis.checkedありがとう@Tim Down
  • optionの選択された状態を取得するthis.selectedTim Downに感謝
  • inputの無効な状態を取得するthis.disabledTim Downに感謝
  • inputのreadOnly状態を取得するthis.readOnlyTim Downに感謝
  • this.href<a>要素に対してhrefを取得します
  • this.hostname<a>要素に対して使用して、そのhrefのドメインを取得します
  • this.pathname要素に対する<a>は、hrefのパスを取得します
  • this.search<a>要素に対して使用して、そのhrefのクエリ文字列を取得します
  • srcを持つことが有効な要素に対するthis.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(spans[0])のために外側のwhileで無限ループを持っているように見えるかもしれませんが、「ライブリスト」を処理しているため、parent.removeChild(span[0]);を実行すると更新されます。これは非常に気の利いた機能で、代わりに配列(または配列のようなオブジェクト)を操作するときに見逃します。

203
user113716

正解は、always 'plain old'ネイティブJavaScriptの代わりにjQueryを使用するとパフォーマンスが低下するということです。 jQueryはJavaScriptライブラリであるためです。 JavaScriptの派手な新しいバージョンではありません。

JQueryが強力な理由は、クロスブラウザーの状況で過度に退屈なものを作成し(AJAXは最良の例の1つ)、無数の使用可能なブラウザー間の不整合をスムーズにし、一貫したAPIを提供するためです。また、チェーン、暗黙の反復などの概念を簡単に促進して、要素のグループでの作業を簡単にします。

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

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

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

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

60
g.d.d.c

というフレームワークがあります。 Vanilla JS 。ジョークを取得することを願っています...:Dパフォーマンスのためにコードの読みやすさを犠牲にします... jQueryと比較すると、DOM要素をIDで取得することはほとんど35Xより高速。 :)

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

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

彼らのホームページにはいくつかのパフォーマンス比較があります:

enter image description here

38

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

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

これはおそらく、どのブラウザでも機能するものと機能しないものの最も包括的なリストです。 DOMセクションに特に注意してください。読むことはたくさんありますが、ポイントはすべてを読むことではなく、参照として使用することです。

Webアプリを本格的に書き始めたとき、すべてのDOMテーブルを印刷して壁に掛けて、何が安全で何がハッキングが必要かを一目でわかるようにしました。最近は、疑わしいときにquirksmode parentNode compatibilityのようなものをグーグルで検索しています。

他のものと同様に、判断はほとんど経験の問題です。サイト全体を読み、jQueryを使用するタイミングとプレーンJSを使用するタイミングを把握するためにすべての問題を記憶することはお勧めしません。リストに注意してください。検索するのは簡単です。時間が経つにつれて、プレーンJSが望ましい場合の本能が発達します。


PS:PPK(このサイトの著者)には、読むことをお勧めする非常に素晴らしい本もあります

17
slebetman

いつ:

  1. あなたがしていることに対して、クロスブラウザのサポートがしっかりとあることを知っている、そして
  2. 入力するコードはそれほど多くありません。
  3. それほど読みにくいわけではなく、
  4. jQueryがパフォーマンスを向上させるためにブラウザーに基づいて異なる実装を選択しないと合理的に確信している場合:

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

編集:この答えは、jQuery全体を使用するか、除外するかを選択する場合と、jQuery内でVanilla JSを使用するかどうかを選択する場合の両方に適用されます。 attr('id').idの間の選択はJSを優先し、removeClass('foo').className = .className.replace( new Regexp("(?:^|\\s+)"+foo+"(?:\\s+|$)",'g'), '' )の間の選択はjQueryを優先します。

14
Phrogz

他の回答は、「jQuery vs. plain JS」という幅広い質問に焦点を当てています。 OPから判断すると、すでにjQueryを使用することを選択している場合、Vanilla JSを使用するほうがよいのではないかと単純に思っていたと思います。あなたの例は、Vanilla JSを使用すべきときの完璧な例です。

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

遅いし、(私の意見では)読みにくい:

this.id

JQueryの方法で属性を取得するためだけに新しいJSオブジェクトをスピンアップする必要があるため、処理が遅くなります。ここで、$(this)を使用して他の操作を実行する場合は、必ずjQueryオブジェクトを変数に格納し、それを操作します。ただし、要素の属性(idsrcなど)だけが必要な多くの状況に遭遇しました。

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

最も一般的なケースは、投稿で説明するケースだと思います。 $(this)を不必要にjQueryオブジェクトにラップする人。私はこれをidvalueでよく見ます(代わりに$(this).val()を使用)。

Edit:ここ は、jQueryを使用してwhyを説明する記事ですattr()の場合は遅いです。告白:タグwikiから盗みましたが、質問で言及する価値があると思います。

もう一度編集:属性に直接アクセスすることの可読性/パフォーマンスへの影響を考えると、おおよその経験則はおそらくthis.<attributename>を使用しようとすることです可能であれば。おそらくブラウザの不整合のためにこれが機能しない場合がいくつかありますが、最初にこれを試して、機能しない場合はjQueryにフォールバックする方が良いでしょう。

13
Andrew Whitaker

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

それは本当に探しているものの例ではありませんが、私はこれを頻繁に見ていますが、言及するに値しません:jQueryスクリプトのパフォーマンスを高速化する最良の方法の1つは、jQueryオブジェクトをキャッシュすることです、および/または連鎖を使用します:

// 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();
10
Stephen

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

8
Dutchie432

これは私の個人的な見解ですが、jQueryはJavaScriptであるため、理論的にはVanilla JSよりも優れたパフォーマンスを発揮できないと思います。

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

結論-小さいものにはVanilla JSを使用する傾向があり、JS集中型のプロジェクトにはjQueryを使用し、車輪を再発明するのが好きではありません-生産性も向上します。

6
CodeVirtuoso

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

他の人を知るのも面白いかもしれません。

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

  • this.formsは、現在のドキュメントフォームのHTMLCollectionを取得します。
  • this.anchorsは、HTMLCollectionが設定されているすべてのHTMLAnchorElementsnameを取得します。
  • this.linksは、HTMLCollectionが設定されているすべてのHTMLAnchorElementhrefを取得します。
  • this.imagesは、すべてのHTMLCollectionHTMLImageElementを取得します
  • this.appletsとして廃止されたアプレットでも同じ

document.formsを使用すると、document.forms[formNameOrId]はそのように名前が付けられた、または識別されたフォームを取得します。

これがフォームの場合:

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

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

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

JQueryセレクターを学習する場合、既存のHTML要素プロパティの学習をスキップすることがよくあります。これはアクセスが非常に高速です。

3
lib3d

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

JQueryを使用することにしたのは、それほど魅力的な追加機能ではありませんでした。結局のところ、あなたはあなた自身の関数を書くことを止めません。

メモリリークを回避するためにDOMを変更する際に学ぶべき非常に多くのトリックがあったという事実でした(私はIEについて話している)。私にとってこれまで以上に優れたJSコーダーだった人々によって書かれた、これらのすべての種類の問題を管理する1つの中央リソースを持つことは、絶えずレビュー、修正、テストされていました。

この種のクロスブラウザーサポート/抽象化引数の下に落ちると思います。

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

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

ただし、通常、パフォーマンスの違いは問題になりません。十分に高速である必要があります。 CPUサイクルのギガヘルツが毎秒無駄になっているため、18か月ごとに電力が2倍にならない唯一の開発リソースであるコーダーのパフォーマンスに関心があります。

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

2
Swanny

これは非技術的な答えです-多くのジョブはjQueryなどの特定のライブラリを許可しません。

実際、GoogleはどのコードでもjQueryを許可していません(Facebookが所有しているため、Reactも許可していません)。 XYZ Corporationの承認済みリスト」。 Vanilla JavaScriptは、いつでもどこでも絶対に動作し、この問題を決して発生させません。ライブラリに依存している場合、スピードと使いやすさは得られますが、普遍性は失われます。

また、面接について言えば、コードクイズ中にJavaScriptの問題を解決するためにライブラリを使用する必要があると言う場合、実際には問題を理解していないように見えます。一方、未加工のVanilla JavaScriptで解決すると、実際に理解し、彼らが目の前に投げた問題のあらゆる部分を解決できることを示します。

2
Jack Connor

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

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

1
John Green