2

apply() メソッドを使用して addEventListener() を呼び出そうとしています。コードは次のようになります。

関数の書き換え(古い){
    関数を返す(){
        console.log( ' + old.name に何かを追加 );
        old.apply(これ、引数);
    }
}
addEventListener=rewrite(addEventListener);

うまくいきません。コードは通常の JavaScript メソッドで機能します。たとえば、

関数 hello_1(){
    console.log("こんにちは世界 1!");
}
hello_1 = 書き換え (hello_1);

助けが必要!

ありがとう!

4

1 に答える 1

9

addEventListener残念ながら、実際の Javascript 関数であるとは期待できません。(これは、 などの他のいくつかのホスト提供関数にも当てはまりますwindow.alert)。多くのブラウザーは Right Thing (tm)を実行し、それらを真の Javascript 関数にしますが、一部のブラウザーはそうしません (Microsoft のことです)。また、それが実際の Javascript 関数でない場合は、プロパティとして関数applyと関数がありません。call

applyしたがって、プロキシからターゲットに任意の数の引数を渡したい場合は、この機能が必要になるため、ホスト提供の関数でこれを一般的に行うことはできません。代わりに、次のように、関連するホスト関数の署名を認識するラッパーを作成するために特定の関数を使用する必要があります。

// Returns a function that will hook up an event handler to the given
// element.
function proxyAEL(element) {
    return function(eventName, handler, phase) {
        // This works because this anonymous function is a closure,
        // "closing over" the `element` argument
        element.addEventListener(eventName, handler, phase);
    }
}

それを呼び出して要素を渡すと、 を介してその要素にイベント ハンドラを接続する関数が返されますaddEventListener。(ただし、IE8 より前の IE には がないことに注意してください。代わりaddEventListenerに使用しattachEventます。)

それがあなたのユースケースに合っているかどうかはわかりません(そうでない場合は、ユースケースの詳細が便利です).

上記を次のように使用します。

// Get a proxy for the addEventListener function on btnGo
var proxy = proxyAEL(document.getElementById('btnGo'));

// Use it to hook the click event
proxy('click', go, false);

proxy呼び出したときに要素参照を渡していないことに注意してください。関数はクロージャーであるため、既に関数に組み込まれています。それらに慣れていない場合は、私のブログ投稿Closures are not complex が役に立つかもしれません。

完全な例を次に示します。

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Test Page</title>
<style type='text/css'>
body {
    font-family: sans-serif;
}
#log p {
    margin:     0;
    padding:    0;
}
</style>
<script type='text/javascript'>

    window.onload = pageInit;
    function pageInit() {
        var proxy;

        // Get a proxy for the addEventListener function on btnGo
        proxy = proxyAEL(document.getElementById('btnGo'));

        // Use it to hook the click event
        proxy('click', go, false);
    }

    // Returns a function that will hook up an event handler to the given
    // element.
    function proxyAEL(element) {
        return function(eventName, handler, phase) {
            // This works because this anonymous function is a closure,
            // "closing over" the `element` argument
            element.addEventListener(eventName, handler, phase);
        }
    }

    function go() {
        log('btnGo was clicked!');
    }

    function log(msg) {
        var p = document.createElement('p');
        p.innerHTML = msg;
        document.getElementById('log').appendChild(p);
    }

</script>
</head>
<body><div>
<input type='button' id='btnGo' value='Go'>
<hr>
<div id='log'></div>
</div></body>
</html>

func.apply()以下のvs.に関する質問については、func()おそらくすでに理解していると思いますが、私の最初の間違った答えが問題を混乱させただけです。ただし、念のため:apply関数を呼び出し、2 つの特別なことを行います。

  1. this関数呼び出しの内容を設定します。
  2. 関数に渡す引数を配列 (または配列のようなもの) として受け入れます。

おそらくご存じのとおり、 Javascript は、C++、Java、C# などの他の言語thisとはまったく異なります。Javascript では、関数が定義されている場所とは関係ありません。関数がどのように呼び出されるかによって完全に設定されます。関数を呼び出すたびに、正しい値を設定する必要があります。( Javascript の詳細については、こちらを参照してください。)これを行うには 2 つの方法があります。thisthisthisthis

  • オブジェクト プロパティを介して関数を呼び出す。this呼び出し内のオブジェクトに設定されます。たとえば、 をfoo.bar()設定thisしてfooを呼び出しますbar
  • 独自のapplyまたはcallプロパティを介して関数を呼び出す。this最初の引数に設定されたもの。たとえば、bar.apply(foo)orbar.call(foo)を設定thisしてfooを呼び出しますbar

applyとの唯一の違いはcall、ターゲット関数に渡す引数を受け入れる方法です。apply配列 (または配列のようなもの) として受け入れます。

bar.apply(foo, [1, 2, 3]);

一方、callそれらを個別の引数として受け入れます。

bar.apply(foo, 1, 2, 3);

どちらも を呼び出しbar、 に設定thisfoo、引数 1、2、および 3 を渡します。

于 2010-05-23T08:48:23.613 に答える