1

John Resig の「Secrets of the Javascript Ninja」を読んでいて、その中で彼はイベント ハンドラーのコンテキストの変更について語っています。その中に彼は次のコードを持っています。なぜそれが機能するのかわかりません。これで非常に失われました。

<body>
    <button id="test">Click Me!</button>

    <script>
      function bind(context,name){                                 //#1
        return function(){                                         //#1
          return context[name].apply(context,arguments);           //#1
        };                                                         //#1
      }                                                            //#1

      var button = {
        clicked: false,
        click: function(){
          this.clicked = true;
          alert('It has been clicked! The value of clicked is ' + clicked);
        }
      };

      var elem = document.getElementById("test");
      elem.addEventListener("click",bind(button,"click"),false);     //#2

    </script>

  </body>

つまり、バインド関数自体がわかりません。また、なぜバインド関数を無名関数にする必要があるのか​​ わかりません。bind() 関数を削除して次のいずれかを試すと、常に「クリックされたものは未定義です」というエラー メッセージが表示されるためです。私にとっては、「this」パラメーターをボタンオブジェクトに割り当てて、クリックされたプロパティにアクセスできるようにすることで、それらのいずれかが機能します。

    elem.addEventListener("click",button.click.apply(button),false);

この次のケースでは、javascript のネイティブの「バインド」機能について話しています。

    elem.addEventListener("click",button.click.bind(button),false); 

私が見る限り、次のステートメントは John Resig の bind() 関数が返すものです

    elem.addEventListener("click",function() { button.click.apply(button, arguments)},false); 

しかし待ってください。John Resig の bind 関数には 2 つの return ステートメントがあります。この時点で私はただ推測しています - この次のものはどうですか?

    elem.addEventListener("click",function() { return button.click.apply(button, arguments)},false); 

上記のステートメントはどれも機能しません。

第 2 に、バインド関数に 2 つの return ステートメントがあるのはなぜですか? 私の考えでは、バインドは次のように機能します。

function bind(context,name){ 
            return function(){ context[name].apply(context,arguments); }; 
          }

第 3 に、John Resig の bind 関数を変数に割り当てようとすると、変数 ninja のようになります。

var ninja = bind(button,"click");
ninja;

返される関数は次のようになると思います。

function(){ button["click"].apply(button,arguments);

context と name の値はクロージャーを介して入力されるためです。代わりに、次のようになります。

function(){ context[name].apply(context,arguments);

だから...これらすべての質問に関する私の混乱の根本的な原因が、私が見逃しているのと同じ基本的な概念に由来することを願っています. 考え?

4

3 に答える 3