2016-10-14 4 views
1

私はUnderscore.jsの注釈付きソースを読んできましたが、通常通りにオブジェクトを_()に渡すときに、this._wrappedをどのように使っているのだろうと思いましたオブジェクトを_オブジェクトの関数に渡します。アンダースコア.jsはthis._wrapをどのように使用しますか

この:対

_(myObj).each(callback); 

_.each(myObj, callback); 

私は最初の関数呼び出しを実行して、開発者向けツールでそれを一時停止すると、最終的にコードはここに終わる:

_.mixin = function(obj) { 
    _.each(_.functions(obj), function(name) { 
    var func = _[name] = obj[name]; 
    _.prototype[name] = function() { 
     var args = [this._wrapped]; 
     push.apply(args, arguments); 
     return result(this, func.apply(_, args)); 
    }; 
    }); 
}; 

しかし、私はそれがそこに行くことを知っていた方法について確信しています。誰かが私にこれを理解させる助けになるだろうか?また、私は前に答えを探してみましたが、この特定の質問は出てこないようです。これが前に答えられていれば、私の謝罪。オブジェクト指向のスタイルでアンダースコアを使用して

答えて

1

_([1, 2, 3]).map(function(n){ return n * 2; }); 

がインスタンス化されるオブジェクトが発生します。簡単に見逃すことができ

var _ = function(obj) { 
    if (obj instanceof _) return obj; 
    if (!(this instanceof _)) return new _(obj); // on this line 
    this._wrapped = obj; 
}; 

魔法newキーワードの欠如であります(コンストラクタとしてではなく)他の関数と同様に関数が呼び出されると、thisは親スコープを参照し(_のインスタンスではない)、012をトリガしますステートメント(およびオブジェクト構造)。 newの使用を強制することを避けることは、非常に巧妙な方法です。

このパターンの実際の動作を確認するには、https://jsfiddle.net/336493L6/を参照してください。

Underscoreオブジェクト(各マップなど)で静的に使用されるすべての関数は、_.mixin関数を使用してUnderscoreプロトタイプに適用されます。もちろん

_.mixin(_); 

を、あなたがデバッグする場合、それは静的関数をラップして、あなたがmixin機能に終わるだろう:

これは、起こるラインです。

_.prototype[name] = function() { 
    var args = [this._wrapped]; 
    push.apply(args, arguments); 
    return result(this, func.apply(_, args)); 
}; 

静的関数のこのプロトタイプ版は、this._wrappedに設定された第1パラメータに静的関数を呼び出します。 resultは、この場合の関数からの戻り値を変更しません(_.chainで使用されます)。

+1

@Tomalak - 誤って読んだことがあります.2行目は '!()'が 'new()を使わずに呼び出された場合です! 'をテストしますが、これが実行されると'new _(obj)'を呼び出すと、最初のif文と2番目のif文の両方に失敗し、3行目に到達します。 – mikeapr4

+0

私が話しているパターンを示すJSFiddleで答えを更新しました – mikeapr4

+0

あなたは正しいです、私は誤解しました。申し訳ありません、気にしないで、続けてください。 :) – Tomalak

関連する問題