47

簡単そうです。引数の配列を使用して関数を呼び出したいと思います。確かに、私は言うことができますが、それは内部func.apply(this, ['some', 'arguments']);の値を変更します。それを変更せずにこれを行う方法はありますか?thisfunc

4

5 に答える 5

31

JavaScriptでの動作方法のため、thisできません。読む:

ECMAScript仕様の「実行コンテキストの入力」セクションを参照してください。関数を呼び出すと、の値は、その残りの部分(アクティベーションオブジェクトthisと呼ばれます)によって決定されます。steveという関数を作成し、彼をオブジェクトに入れましょう。

function steve(){}
var obj = { method: steve };

…steveをと呼ぶと、アクティベーションオブジェクトだったのでobj.method()、彼thisはです。objobj

トリッキーなケースは、関数呼び出しの左側に何もない場合です。

steve(); // Who am I ?!

関数呼び出しの左側には何もありません—事実上null そうです—したがって、の値はthisグローバルオブジェクトのデフォルト値に設定されます(windowWebブラウザー、globalNode.jsなど)。

つまり、実際には、関数thisを呼び出すたびに関数を設定していることになります。

PSの呼び出しsteve.apply(null, [])は、の呼び出しと同じsteve()です。

于 2011-03-09T14:45:38.597 に答える
13

ES6では、次のように書くこともできます。

func(...someArray)

ここthisWindow内側になりますがfunc、これは役に立ちません。しかし、あなたが書くなら:

obj.func(...someArray)

this中にfuncはなりますobj

これは私が5年前に探していた機能かもしれませんが、それは5年前だったので、誰が覚えていますか:)

于 2016-09-06T07:31:11.640 に答える
3

関数を呼び出すときの値は、「通常」(またはなし)thisと呼ばれる方法に応じて、謎ではありません。callapply

func(); // `this` is the global object, or undefined in ES5 strict mode
obj.func(); // `this` is `obj`

したがって、の値を「変更」しないようにするには、「通常」と呼ぶ方法に応じてthis、正しい値をに渡すだけです。apply

func.apply(undefined, []); // global object, or undefined in ES5 strict mode
obj.func.apply(obj, []);
于 2011-03-09T14:56:12.147 に答える
2

関数を単独で呼び出す場合は、を渡しnullます。

func.apply(null, ['some', 'arguments']);

オブジェクトのメソッドである関数を呼び出す場合は、そのオブジェクトを渡します。

var arr = [];
arr.push.apply(arr, ['some', 'arguments']);

これがどのように機能するかを一致させるために。

于 2011-03-09T14:30:36.840 に答える
0

あなたが望むものはあまり意味がありません。

ecmascript標準thisでは、次のように定義されています。

11.1.1 thisキーワードthisキーワードは、現在の実行コンテキストのThisBindingの値に評価されます。

関数実行コンテキストのthisBinding解決は、次のように指定されます。

10.4.3関数コードの入力制御が関数オブジェクトFに含まれる関数コードの実行コンテキストに入ると、次の手順が実行されます。呼び出し元はthisArgを提供し、呼び出し元はargumentsListを提供します。

  1. 関数コードが厳密なコードである場合は、ThisBindingをthisArgに設定します。
  2. それ以外の場合、thisArgがnullまたは未定義の場合は、ThisBindingをグローバルオブジェクトに設定します。
  3. それ以外の場合、Type(thisArg)がObjectでない場合は、ThisBindingをToObject(thisArg)に設定します。
  4. それ以外の場合は、ThisBindingをthisArgに設定します。
  5. localEnvを、引数としてFの[[Scope]]内部プロパティの値を渡してNewDeclarativeEnvironmentを呼び出した結果とします。
  6. LexicalEnvironmentをlocalEnvに設定します。
  7. VariableEnvironmentをlocalEnvに設定します。
  8. codeをFの[[Code]]内部プロパティの値とします。
  9. 10.5で説明されているように、関数コードコードとargumentListを使用して、宣言バインディングのインスタンス化を実行します。

つまり、指定するか、グローバルオブジェクトに自動的に設定されます。親スコープからthisバインディングを継承することは決してないため、親スコープのthisBindiongをその子に与える唯一の方法は次のいずれかです。

  1. varのような親スコープのローカル変数に保存しますself = this
  2. 質問で指定したコードのように、call/applyを挿入します。
于 2011-03-09T14:48:59.690 に答える