2

私は JavaScript を実際に使用したことはありませんが、それが何であるかは大まかに知っています。今、Chrome 拡張機能の例をいくつか調べていると、この「パターン」がかなり多く見られます。

var Main = {
    enable: function(){ window.addEventListener('mousemove', onMouseMove, false); },
    onMouseMove: function(event){ _onMouseMove(event) },
    _onMouseMove: function(event){
        ...lenghty implementation...
    }
}

私の質問は、なぜですか?これはある種の最適化ですか?

4

4 に答える 4

3

質問は少し曖昧です。onMouseMoveしかし、開発者がすべての作業を1つで行うのではなく、2つの方法を使用する理由を尋ねていると思います。つまり、次のようになります。

var Main = {
    onMouseMove: function(event) { 
        // Why not just have the implementation here?
        // Why are we delegating it to the other method?
        _onMouseMove(event) 
    },
    _onMouseMove: function(event){
        // ...length implementation...
    }
}

答えは、JavaScriptでスコープがどのように処理されるかによるものです。一言で言えば、thisほとんどの古典的なOOP言語(Javaなど)のキーワークは、常にMain関数のスコープ内の親クラス()を参照します-JavaScriptはこのようには機能しません。

JavaScriptには古典的なクラスがないため、thisキーワードは実際にはそれを呼び出した関数を参照します。そのため、newコンストラクター関数を介して新しいオブジェクトを作成するときに、キーワードがそのような違いを生み出します。例えば:

function MyConstructor = function () { 
    // Assign a member property
    this.aProperty = "An Example";
}

// Using the new keyword; a new scope is created for the call which refers to the
// object about to be created (and returned).
var withNew = new MyConstructor();
console.log(withNew.aProperty);  // 'An Example'

// Without the new keyword...
var withoutNew = MyConstructor();
console.log(withoutNew.aProperty);  // undefined

// Because we didn't use new, the calling function scope was applied, so 
// the `this` keyword resolves caller's scope.
console.log(this.aProperty)  // 'An Example'

から委任することによりonMouseMove_onMouseMoveスコープはMain、マウスイベントをトリガーしたオブジェクトにバインドされるのではなく、オブジェクトにバインドされたままになります。これを実現するもう1つのより読みやすい方法は、デリゲートを使用することです。ES5を使用している場合は、Function.bindを使用します。

var Main = {
    enable: function() {
        window.addEventListener('mousemove', onMouseMove.bind(this), false); 
    },
    onMouseMove: function(event) { 
        // ...lengthy implementation...
    }
}
于 2012-05-06T17:51:20.283 に答える
1

私はクロム拡張機能が一般的に実装される方法に精通していませんが、このパターンを使用するときは、特に実装を保護するためです。

通常、プラグインは特定のプロパティと機能を公開します。その関数のユーザーは、公開された関数を簡単に (誤って) オーバーライドできます。その場合、その関数に実際の実装がある場合、それはなくなります。

更新:質問を更新したので...

onMouseMove個人的には、オブジェクトの一部と as の両方を公開する価値はあまりない_onMouseMoveと思います。_私は、人々が「規則を守り」、接頭辞が付いたプロパティを非公開として扱うといういくつかの仮定に基づいて、このように記述された JavaScript ライブラリを見てきました。

おそらく、私は次のようなことをするでしょう:

var Main = function(){
   var _onMouseMove = function(event){ ... do stuff...};
   return {
       enable: function(){...},
       onMouseMove: _onMouseMove
   }
}
于 2012-05-06T17:25:47.517 に答える
1

いいえ、これは最適化ではありません (少なくとも私が知る限り)。

私はクロム拡張機能についてあまり知識がありません。時々コードを読むだけで、深刻なことは何もありません。しかし、あなたが求めているパターンは、ブライトガーデンが言ったように、実装を保護することです。他の言語では、プライベート データをカプセル化するメカニズムが組み込まれています。js にはありません。これは大まかに、非常に大まかに、一種のモジュールパターンのように思えます-その例はすでにブライトガーデンの回答に示されています。js で実装されたデザイン パターンの詳細については、http://addyosmani.com/resources/essentialjsdesignpatterns/book/ を参照してください。

具体的 には、モジュール パターンのhttp://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascriptです。

実際のモジュールパターンは、例よりも優れており、混乱が少ないです。

于 2012-05-06T17:41:23.720 に答える
0

その「パターン」には、読者を混乱させる以外の利点はありません。

于 2012-05-06T17:39:27.210 に答える