例1の問題は、myNameオブジェクトではなくグローバル名を参照する「this」です。
この値を特定のオブジェクトに設定する際のbind()の使用を理解しているので、例1の問題は解決しますが、この問題が最初に発生するのはなぜですか? Javascriptが作成されたのと同じ方法ですか?
また、例3が問題と例2と例3の違いを解決する理由も疑問に思っています。
this.name = "John"
var myName = {
name: "Tom",
getName: function() {
return this.name
}
}
var storeMyName = myName.getName; // example 1
var storeMyName2 = myName.getName.bind(myName); // example 2
var storeMyName3 = myName.getName(); // example 3
console.log("example 1: " + storeMyName()); // doesn't work
console.log("example 2: " + storeMyName2()); // works
console.log("example 3: " + storeMyName3); // works
JavaScript bind()が必要なのはなぜですか?
this
の値は、how関数によって決定されますcalled。関数を呼び出すのがyouの場合、関数の呼び出し方法を制御できるため、通常_.bind
_を使用する必要はありません。 、したがってそのthis
値。
ただし、多くの場合、関数を呼び出すのはnotです。関数は、コールバックおよびイベントハンドラーとして他の関数に渡されます。それらはotherコードによって呼び出され、howを制御することはできません関数が呼び出されるため、this
が参照するものを制御できません。
関数でthis
を特定の値に設定する必要があり、自分が関数を呼び出しているのではない場合、特定のthis
値に関数を_.bind
_する必要があります。
つまり、_.bind
_を使用すると、関数nowを呼び出さずにthis
の値を設定できます。
以下は、関数の参照/呼び出しの比較です。
_ +-------------------+-------------------+
| | |
| time of | time of |
|function execution | this binding |
| | |
+-------------------+-------------------+-------------------+
| | | |
| function object | future | future |
| f | | |
| | | |
+-------------------+-------------------+-------------------+
| | | |
| function call | now | now |
| f() | | |
| | | |
+-------------------+-------------------+-------------------+
| | | |
| f.call() | now | now |
| f.apply() | | |
| | | |
+-------------------+-------------------+-------------------+
| | | |
| f.bind() | future | now |
| | | |
+-------------------+-------------------+-------------------+
_
また、例3が問題と例2と例3の違いを解決する理由も疑問に思っています。
例1/2と3はこれ以上違いはありません。 storeMyName
および_storeMyName2
_にはfunctionsが含まれます。これらは将来呼び出されますが、_storeMyName3
_には次の結果が含まれます。その時点でmyName.getName()
を呼び出しています。
その他の資料:
bind()
メソッドは、新しい関数が呼び出されたときに、指定された値にthisキーワードが設定された新しい関数を作成します。
そのため、初めて_var storeMyName = myName.getName;
_を実行すると、グローバルname
(this.name = "John")が使用されます
bind()
関数を使用すると、現在のクロージャーで定義されている名前(この場合はmyName)の参照が開始されるため、Tom
が出力されます。
3回目、関数はすぐに呼び出されるため、そのスコープは独自のローカルオブジェクト内にあり、クロージャーTom
に値を出力します。
バインドは、実行のコンテキスト(ここではデフォルトのコンテキストはグローバル)を変更できるメカニズムです。
あなたの例に基づいて-
var storeMyName = myName.getName;
上記の行から、グローバルコンテキストでstoreMyName
関数を実行しているため、この実行ではthis.name
が最上行(つまり、グローバル1/"John")になります。
var storeMyName2 = myName.getName.bind(myName);
上記の行では、明示的にstoreMyName2
関数の実行コンテキストを変更します(この関数をグローバル関数として実行したくないと言うことで、この関数をコンテキストで実行したいmyName
オブジェクト。この場合、this.name
は "Tom"になります)
var storeMyName3 = myName.getName(); // example 3
そして、上記の行では、myName
オブジェクトコンテキストで関数を実行しているだけです。さらに重要なことは、storeMyName3
を実行していないため、そのコンテキストはグローバルではありません。
私が好きな類推、どこにも見たことがない:bar
関数を持つfooオブジェクトがあるとしましょう。 bar関数を別の変数にバインドする(またはコールバックでより一般的なケースである関数パラメーターとして渡す)場合、その関数を囲むオブジェクトではなく、「ヌード」関数のみでバインド/渡します。したがって、「ヌード」関数では、this
はグローバルオブジェクトを意味します。
小さなデモ
_var foo = "global foo"; //foo set on the global object
var a = {foo : "object foo", bar : function(){return this.foo;}};
var bound = a.bar;
console.log(bound());//returns "global foo", not "object foo"
_
bound
はfunction(){return this.foo;}
を指すだけです