2016-09-06 16 views
2

jquery $をエミュレートするjavascriptを見ているうちに、私はこのシナリオではreturnが必要な理由を理解できません。ここでreturn文が必要な理由を理解できない

は私が

$ = function(selector){ 
      if (!(this instanceof $)) { 
       return new $(selector); 
      } 
     var elements = document.querySelectorAll(selector); 

     Array.prototype.push.apply(this,elements); 

    }; 

で探していたコードで新しい$(セレクタ)を返すことがちょうど新しい$(セレクタ)動作しない理由を誰かが私に説明していただけますか?あなたがリターンをするとき、最初から新しいキーワードですべてを始めるのですか?私はこれを描くのに苦労している。助けてください。

申し訳ありませんが、私はこの非常に明確にしていない場合。私の質問は、ステートメントのreturn new $(セレクタ)がちょうど新しい$(セレクタ)と異なるvsを実行していることです。このif文の中にデバッガを置いてウォッチャをthisに置くと、最初はthisがウィンドウになり、関数をステップ実行すると、新しい$(セレクタ)を返して実行した後、if文に戻るこれがinstanceof $の場合(今はthisが$を指しているので)それがどうして私の質問です。誰かが "新しい$(セレクタ)を返す"ときに誰かに教えてもらえますか?

答えて

3

あなたがクラスオブジェクトではなくインスタンスオブジェクトを扱っていることを確認するのは、共通のJavaScriptイディオムです。

(JavaScriptが技術的プロトタイプベースのオブジェクトシステムであるが、クラス/インスタンスの区別はこの関係を記述するための最も一般的/認識可能なメタファーである。)

$ = function (selector) ...オブジェクトのどの「クラス」を定義動作します。新しいオブジェクトをインスタンス化するために$(...)を呼び出すたびに権利によって、実際にはクラスの新しいインスタンスを返すためにnew $(...)に電話する必要があります。 $(...)は単なる関数呼び出しではありません。意図では、それはコンストラクタです。クラスの新しいインスタンスがどのように形成されるかを定義します。その少しinstanceofテストとreturn new $(selector)は必要なものを自動化していますnew - それは忘れることは信じられないほど簡単ですが、実際には使用しないことがよくあります。ガード状態があるので、newを手動で呼び出さなければなりません。ガード条件の内側

$ = function(selector) { 
     if (!(this instanceof $)) { 
      // if was called naked, without new, auto-new an instance 
      return new $(selector); 
     } 
    // by time execution arrives here, we have guaranteed that we are 
    // dealing with an instance of $, not $ itself (i.e. an instance not 
    // the class) 
    var elements = document.querySelectorAll(selector); 

    // use Array class to make this instance an array-like 
    // object holding the selected DOM elements 
    Array.prototype.push.apply(this,elements); 
    }; 

更新/明確化returnnew $(...)の値を返す、すぐに初期$(...)コールを終了します。これは基本的には再帰的な定義です - 最大で1回のみ再帰を繰り返す些細な再帰のケースですが。考慮する論理的なケースは2つあります。

  1. $(...)が呼び出された場合、再帰と戻り値はnew $(...)です。 returnが使用されていない場合、JavaScript関数はデフォルトでundefinedを返しますので、returnが必要です。したがって、コードは明示的にnew ...の値を返す必要があります。
  2. new $(...)が呼び出された場合(直接、またはガード条件からの些細なワンステップ再帰によって)、インスタンスを処理しています。適切なノードを見つけるにはdocument.querySelectorAllを、このインスタンスにノードをロードするにはArray.prototype.pushを使用してください。この場合はreturnが必要です。これは、new関数呼び出しに固有の魔法であり、常に作成されたインスタンスを返します。だから、必要なだけインスタンスをロードするだけです。自動的に返されます。

このように、一般的な使用法は、このように書きます:再帰そう

  1. $('p.main')は元のコール

  2. $機能をチェックしていると、それはがないインスタンスを扱っていない見つけ、 、コールnew $('p.main')

  3. $は2番目の再帰呼び出しで機能し、現在インスタンスを処理しています。 DOMノードをこのインスタンスにロードし、暗黙的に のnewの魔法の特殊処理を使用して返します。

  4. 新しいインスタンスは、元の呼び出しのガード条件に戻されます。 それは明示的にreturnはそれがあったので、外、元のコールがないないようないもともと、新しいと と呼ばれる値がnew魔法 autoreturnを楽しむ必要があります。新しい インスタンスを元の呼び出し元に明示的に返します。

+0

申し訳ありませんが、私は「新しい」というキーワードが何をしているのか尋ねていません。私はなぜ、「復帰」が必要なのかを尋ねています。 – user3502374

+0

元の投稿に編集後の記事を長くしました。私の質問が今ではっきりしているかどうか見ることができますか? – user3502374

+0

私は、返品がどのように呼び出されたかについて、はるかに詳細な吹き飛ばしの口座を追加しました。 –

1

これは、メソッドと対話するために必要なときに毎回new $("yourSelector")を実行する必要性を避けるためです。行this instanceof $は、関数そのものではなく、関数のインスタンス化されたバージョンの内部にあるかどうかを調べます。

(this instanceof $)falseの場合、return new $(selector)を実行して関数をインスタンス化する必要があります。帰りは重要です。なぜなら、私たちはその時点で正常な機能の中にいるからです。このようにして、我々は現在$という関数を呼んでいても、常にインスタンスを戻します。

+0

私は元の投稿にもっと長い編集を加えました。どうぞご覧ください。 – user3502374

0

私はこの上の明確な公式文書の欠如がある私は、この全体のことについてとても不安だ何だと思う(または私はそれらを見つけることができないのですか、私は)はっきりと(十分に研究されていないしていない。

私が見つけました古い質問と回答以下から非常に良い例

How does using a return clause before a recursive function call differ from not using one?

これは、この例があります。私のnの

function loop(x) { 
    if (x >= 10) 
    return x; 
    loop(x + 1); // the recursive call 
} 
loop(0); 

をあなたが反復したときのように見え、最終的にxが10になるとき、それはreturn xと言う。今、私は仮定している、これは呼び出し元に戻ります(これはループ(x + 1)ですか?)。そしてreturn文がないので、全体がundefinedを返す。これは正しいですか??

関連する問題