0

私が構築している Web アプリの一部として、サーバーから一度に複数のコマンドを受け取ることができます。

これらのコマンドが処理されると、データが更新される傾向があり、かなり重いページ HTML 生成が発生する可能性があります。

複数の同様のコマンドが入った瞬間に、プログラムはデータを処理し、ページの一部が毎回再生成されます。これにより、多くの無駄な処理時間が発生する可能性があります。

そのため、コールスタックを作成しようとしているため、コマンドが処理されると、コマンドがトリガーする関数がスタックにあるかどうかが確認され、見つからない場合は追加されます。


私の問題は、コールスタックから呼び出された関数を正しいスコープに保ちながら、重複を排除できることです。

ベースコード:

var tools = {
  functions:{
    function1: function(){
      return this;
    },
    function2: function(){
    }
  },
  unique: function(arr){
    var returnArr=[],
        x, i;

    for (x=0; x<arr.length; x++){
      for (i=(x+1); i<arr.length; i++){
        if (arr[x]===arr[i]){
          arr.splice(i, 1);
        }
      }
      returnArr.push(arr[x]);
    }

    return returnArr;
  }
}

例 1:

var callstack=[tools.functions.function1, tools.functions.function1];

callstack = tools.unique(callstack);

for (var x=0; x<callstack.length; x++){
  console.log(callstack[x](), "should equal tools.functions");
}

「this」は [function()] を返すため、これは失敗します。


例 2:

var callstack=[
  (function(){return tools.functions.function1()}),
  (function(){return tools.functions.function1()})
];

callstack = tools.unique(callstack);

for (var x=0; x<callstack.length; x++){
  console.log(callstack[x](), "should equal tools.functions");
}

関数が一意であることを保証できないため、これは失敗します。そのため、関数は 2 回実行されます。


これは、2 つの配列 (関数の名前を追跡するものと、カプセル化された関数を保持するもの) を使用して同期を保つことで回避できますが、.電話しても見えない。

JSFiddle: http://jsfiddle.net/Kj6E8/

4

2 に答える 2

1

JavaScriptではthis、外部の呼び出し元から定義されているため、次のようにします。

callstack[x]()

windowスコープを関数に取り込みます。tools.functionsオブジェクトを持ち込みたい場合は、次のことを行う必要があります。

callstack[x].call(tools.functions);

http://jsfiddle.net/Yv4sM/

于 2012-11-01T10:54:43.150 に答える
1

一般的に言えば、this必要な方法で の値を保持することは不可能です。これらの関数を配列にプッシュするとすぐに、それらの関数がかつて存在していたオブジェクトは失われます。

1 つのオブジェクトに対してのみ関数を呼び出す場合は、何らかの方法で関数をそのオブジェクトにバインドする必要があります。これを行うには多くの方法があります。たとえば、それらの関数をバインドするオブジェクトを独自の関数に渡すことができます。

http://jsfiddle.net/8WAZb/1/

var tools = {
  functions:{
    function1: function(){
      return this;
    },
    function2: function(){
    }
  },
  unique: function(arr, o){
    var returnArr=[],
        x, i;

    for (x=0; x<arr.length; x++){
      for (i=(x+1); i<arr.length; i++){
        if (arr[x]===arr[i]){
          arr.splice(i, 1);
        }
      }
        returnArr.push(this.bind(arr[x], o));
    }

    return returnArr;
  },
  bind: function(f, o) {
      return function () {
          return f.apply(o, arguments);
      }
  }
}

console.info("Example 1:");
var callstack=[tools.functions.function1, tools.functions.function1];
callstack = tools.unique(callstack, tools.functions);
console.log("Callstack:",callstack);
for (var x=0; x<callstack.length; x++){
  console.log(callstack[x](), "should equal tools.functions");
}

の値を推測する方法とタイミングthisは、そのオブジェクトがいつスコープ内にあるかによって異なります。おそらく、コールスタックの作成段階でそのオブジェクトをスコープ内に持つ可能性が高く、コールスタック内の関数を呼び出したい時点で必ずしもそうであるとは限りません。その場合は、できるだけ早い段階で (つまり、示されているように一意の呼び出しスタックへの削減中に) バインドすることが賢明なオプションのように思えます。

于 2012-11-01T11:14:12.600 に答える