簡単そうです。引数の配列を使用して関数を呼び出したいと思います。確かに、私は言うことができますが、それは内部func.apply(this, ['some', 'arguments']);
の値を変更します。それを変更せずにこれを行う方法はありますか?this
func
5 に答える
JavaScriptでの動作方法のため、this
できません。読む:
ECMAScript仕様の「実行コンテキストの入力」セクションを参照してください。関数を呼び出すと、の値は、その残りの部分(アクティベーションオブジェクトthis
と呼ばれます)によって決定されます。steveという関数を作成し、彼をオブジェクトに入れましょう。
function steve(){}
var obj = { method: steve };
…steveをと呼ぶと、アクティベーションオブジェクトだったのでobj.method()
、彼this
はです。obj
obj
トリッキーなケースは、関数呼び出しの左側に何もない場合です。
steve(); // Who am I ?!
関数呼び出しの左側には何もありません—事実上null
そうです—したがって、の値はthis
グローバルオブジェクトのデフォルト値に設定されます(window
Webブラウザー、global
Node.jsなど)。
つまり、実際には、関数this
を呼び出すたびに関数を設定していることになります。
PSの呼び出しsteve.apply(null, [])
は、の呼び出しと同じsteve()
です。
ES6では、次のように書くこともできます。
func(...someArray)
ここthis
がWindow
内側になりますがfunc
、これは役に立ちません。しかし、あなたが書くなら:
obj.func(...someArray)
this
中にfunc
はなりますobj
。
これは私が5年前に探していた機能かもしれませんが、それは5年前だったので、誰が覚えていますか:)
関数を呼び出すときの値は、「通常」(またはなし)this
と呼ばれる方法に応じて、謎ではありません。call
apply
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, []);
関数を単独で呼び出す場合は、を渡しnull
ます。
func.apply(null, ['some', 'arguments']);
オブジェクトのメソッドである関数を呼び出す場合は、そのオブジェクトを渡します。
var arr = [];
arr.push.apply(arr, ['some', 'arguments']);
これがどのように機能するかを一致させるために。
あなたが望むものはあまり意味がありません。
ecmascript標準this
では、次のように定義されています。
11.1.1 thisキーワードthisキーワードは、現在の実行コンテキストのThisBindingの値に評価されます。
関数実行コンテキストのthisBinding解決は、次のように指定されます。
10.4.3関数コードの入力制御が関数オブジェクトFに含まれる関数コードの実行コンテキストに入ると、次の手順が実行されます。呼び出し元はthisArgを提供し、呼び出し元はargumentsListを提供します。
- 関数コードが厳密なコードである場合は、ThisBindingをthisArgに設定します。
- それ以外の場合、thisArgがnullまたは未定義の場合は、ThisBindingをグローバルオブジェクトに設定します。
- それ以外の場合、Type(thisArg)がObjectでない場合は、ThisBindingをToObject(thisArg)に設定します。
- それ以外の場合は、ThisBindingをthisArgに設定します。
- localEnvを、引数としてFの[[Scope]]内部プロパティの値を渡してNewDeclarativeEnvironmentを呼び出した結果とします。
- LexicalEnvironmentをlocalEnvに設定します。
- VariableEnvironmentをlocalEnvに設定します。
- codeをFの[[Code]]内部プロパティの値とします。
- 10.5で説明されているように、関数コードコードとargumentListを使用して、宣言バインディングのインスタンス化を実行します。
つまり、指定するか、グローバルオブジェクトに自動的に設定されます。親スコープからthisバインディングを継承することは決してないため、親スコープのthisBindiongをその子に与える唯一の方法は次のいずれかです。
- varのような親スコープのローカル変数に保存します
self = this
- 質問で指定したコードのように、call/applyを挿入します。