15

これを解決しようとすると少し頭痛がします。私がやりたいのは、引数を使用してカスタムsetTimeoutを設定し、それを渡すための関数を作成する必要がないことです。コードで説明させてください:

避けたい:

function makeTimeout(serial){
  serial.close();
}

setTimeout(makeTimeout(sp.name), 250);

私がやりたいのは、どういうわけか、次のように1ライナーを呼び出すことです。

setTimeout(function(arg1){ .... }(argument_value), 250);

これを行うことはできますか、それとも引数なしの関数のみを渡すことができますか?

4

4 に答える 4

24

makeTimeout指定された引数で呼び出す無名関数を渡すことができます。

setTimeout(function () {
  makeTimeout(sp.name);
}, 250);

を使用して、別の方法もありますbind

setTimeout(makeTimeout.bind(this, sp.name), 250);

ただし、この機能はECMAScript 5th Editionの機能であり、すべての主要なブラウザーでまだサポートされているわけではありません。互換性のために、MDNで利用可能なbindソースを含めることができます。これにより、ネイティブでサポートされていないブラウザで使用できるようになります。

デモ

于 2012-09-17T00:27:32.837 に答える
7

別の関数を宣言したくない場合は、すぐに呼び出される関数式とクロージャーを使用できます。

// Parameter to use
var bar = 'bar';

// Function to call
function foo(arg) {
  alert(arg);
}

// Go…
setTimeout(
  (function(arg1){
    return function(){
      foo(arg1);
    };
  }(bar)), 2000);

または、関数コンストラクターを使用することもできます。

setTimeout( Function('foo(bar)'), 2000);

または、文字列を使用できます。

setTimeout('foo(bar)', 1000);

これは本質的に同じことです。「しかし、それはevalを使用するようなものであり、evalが悪であり、大規模なセキュリティ違反であることを誰もが知っています。あなたの長子はすべて運命にあります!

しかし、真剣に、eval(および関数コンストラクター)は非効率的であり、遅延プログラミングにつながる可能性があるため、上記の最初のような別のオプションを使用してください。

于 2012-09-17T01:46:43.690 に答える
3

一部のブラウザに機能が追加され、パラメータをsetTimeoutに渡すようです。

構文:( setTimeout (function (p1,p2) {},1000,p1,p2); 必要な数のパラメーターを追加します)

どこでも機能するようにしたい場合は、添付のコードを使用できます。

注:インストール直後にタイムアウトを設定する場合は、コールバックパラメーターを使用してそこで実行することをお勧めします

例えば

installSwizzledTimeout(function(param1,param2){
    setTimeout(myFunc,200,param1,param2);},param1,param2);
}

これは、非常に短いタイムアウトを設定し、パラメーターをカウントすることにより、必要かどうかを検出するためのトリックを使用しているためです。

window.swizzledSetTimeout = function (fn, ms) {
    if (arguments.length === 2) {
        //console.log("Bypassing swizzledSetTimeout");
        return window.originalSetTimeout(fn, ms);
    } else {
        var args = [];
        for (i = 2; i < arguments.length; i++) {
            args.push(arguments[i])
        };
        //console.log("Setting swizzledSetTimeout for function (",args,") {...} in ",ms," msec");
        var retval = window.originalSetTimeout(function () {
            //console.log("Invoking swizzledSetTimeout for function (",args,") {...}");
            fn.apply(null, args);
        }, ms);
        return retval;
    }
}

function installSwizzledTimeout(cb) {
    var args = [];
    for (i = 1; i < arguments.length; i++) {
        args.push(arguments[i])
    };
    setTimeout(function (arg) {
        //console.log("arguments.length:",arguments.length,window.setTimeout.toString());
        if (arguments.length == 0) {

            function doInstall() {
                //console.log("Installing new setTimeout");
                window.originalSetTimeout = window.setTimeout;
                window.setTimeout = function setTimeout() {
                    return window.swizzledSetTimeout.apply(null, arguments);
                };
                if (cb) {
                    cb.apply(null, args);
                };
            }

            if (window.setTimeout.toString().indexOf("swizzledSetTimeout") < 0) {
                doInstall();
            }
        } else {
            //console.log("existing set time supports arguments ");
            if (cb) {
                cb.apply(null, args);
            };
        }
    }, 0, 1, 2, 3, 4);
}
于 2014-06-23T08:12:05.640 に答える
0

最終的に実行される関数へのパラメーターも持つ一定のタイムアウト設定が必要なメソッドがあったので、無名関数を使用して次のようにしました。

function checkPageLoaded(checker, callback, nextCallTime) {
    return () => {
        let checkoutLoader = document.querySelector(checker);
        if(checkoutLoader === null)
            callback();
        else
            setTimeout(checkPageLoaded(checker, callback, nextCallTime), nextCallTime);
    }
}

そしてそれを次のように呼びます:

setTimeout(checkPageLoaded('.loader', reloadPagination, 500), 500);

このように、引数を使用して実行する目的の関数は、匿名関数として定義された関数になります。

于 2019-11-20T22:40:22.137 に答える