0

次のような関数があるとしましょう。

var meowLikeACat = function(howoften) { 
    setInterval(function() { 
        alert("meow"); 
    },howoften*1000) 
}

そして、私がそれをこのように呼んでいるとしましょう:

var howOften_local = 3;
meowLikeACat(howOften_local+1);

+1その操作は実際にどの時点で発生しますか?

そして、関数が実行される前に渡されていたデータを「インターセプト」することは可能でしょうか?

4

2 に答える 2

3

+1その操作は実際にどの時点で発生しますか?

すべてのパラメーターは、関数に渡される直前に、左から右に評価されます。

11.2.3関数呼び出し

プロダクションCallExpressionMemberExpression *引数*は次のように評価されます。

  1. MemberExpressionを評価した結果をrefとします
  2. funcをGetValueref)とします。
  3. argListを引数の評価の結果とし、引数値の内部リストを生成します(11.2.4を参照)。
  4. Typefunc)がObjectでない場合は、 TypeError例外をスローします。
  5. IsCallablefunc)がfalseの場合、 TypeError例外をスローします。
  6. Typeref)がReferenceの場合、
    a。IsPropertyReference (ref)がtrueの場合、i     。thisValueをGetBaseref)とします。 b。それ以外の場合、 refのベースはEnvironmentRecordiです     。thisValueを、 GetBaseref )のImplicitThisValue具象メソッドを呼び出した結果とします


  7. それ以外の場合、Typeref)はReferenceではありません。
    a。thisValueを未定義とします。
  8. funcで[[Call]]内部メソッドを呼び出した結果を返し、thisValuethis値として提供し、リストargListを引数値として提供します。

11.2.4引数リスト

引数リストを評価すると、値のリストが生成されます(8.8を参照)。

プロダクション引数( )は次のように評価されます:

  1. 空のリストを返します。

本番引数( ArgumentList )は次のように評価されます。

  1. ArgumentListの評価結果を返します。

プロダクションArgumentListAssignmentExpressionは次のように評価されます。

  1. refをAssignmentExpressionの評価結果とします
  2. argをGetValue (ref)とします
  3. 唯一の項目がargであるリストを返します。

本番のArgumentListArgumentListAssignmentExpressionは、次のように評価されます。

  1. previousArgsをArgumentList評価結果とします。
  2. refをAssignmentExpressionの評価結果とします
  3. argをGetValue (ref)とします。
  4. 長さがpreceedingArgsの長さより1つ長く、アイテムがpreceedingArgsのアイテムであるリストを順番に返し、最後に新しいリストの最後のアイテムであるargが続きます。

そして、上記のいずれかで操作を強制的に発生させる方法はありますか?

最初の2つは同じです。関数が呼び出された時間とパラメーターが関数に渡された時間をどのように区別できるかわかりません。

代わりに関数を渡すことで、3番目を達成できます。

function meowLikeACat(howoften) {
    setInterval(function() { 
        alert("meow"); 
    }, howoften()*1000) 
}

var howOften_local = 3;
meowLikeACat(function () {
    return howOften_local+1;
});

そして、関数が実行される前に渡されていたデータを「インターセプト」することは可能でしょうか?

コードが敵意ではなく協力を前提としている場合、これは簡単です。

function meowLikeACat(howoften) { 
    setInterval(function() { 
        alert("meow"); 
    }, howoften*1000) 
}

function intercept(thisArg, original, before) {
    return function() {
        // could manipulate arguments here,
        // or pass something completely different to original
        before.apply(thisArg, arguments);
        original.apply(thisArg, arguments);
    };
}

function doBefore() {
    console.log('before', arguments);
}

var meowLikeACatIntercepted = intercept(null, meowLikeACat, doBefore);

デモ: http: //jsfiddle.net/mattball/e4AY6

于 2013-03-05T03:51:59.273 に答える
1

それはその場で起こります。

var howOften_local = 3;
meowLikeACat(howOften_local+1);

このコードは基本的に次のように実行しています。

meowLikeACat(4);
于 2013-03-05T03:51:53.470 に答える