まず例を見てみましょう
function foo() { console.log( this.a ); } var obj = { a: 2, foo: foo }; obj.foo(); // 2
foo が実行されるときの呼び出しサイト (呼び出し時のスコープとして理解できます) は obj の上にあるため、これは obj を指します。これは実行時のものであり、宣言された場所とは関係がないことに注意してください。
呼び出しサイトと呼び出しスタック
Call-site は一時的に呼び出しドメインとして理解され、call-stack は呼び出しスタックです。次のコードは、
を理解するのに役立ちます。function baz() { // call-stack is: `baz` // so, our call-site is in the global scope console.log( "baz" ); bar(); // <-- call-site for `bar` }
baz() で bar() を呼び出すと、bar の呼び出し元ドメインは baz になります。このとき、bar の呼び出しスタックは baz のみであり、baz 自体はグローバル スコープで公開されるため、その呼び出し先ドメインも影響を受けます。ドメイン内のグローバル スコープ。
function bar() { // call-stack is: `baz` -> `bar` // so, our call-site is in `baz` console.log( "bar" ); foo(); // <-- call-site for `foo` } function foo() { // call-stack is: `baz` -> `bar` -> `foo` // so, our call-site is in `bar` console.log( "foo" ); } baz(); // <-- call-site for `baz`
それを理解した後、最初の例を振り返ると、より明確になります。実際、これは呼び出しサイトを指しているだけです
次のような遊び方もあります:
function foo() { console.log( this.a ); } var obj2 = { a: 42, foo: foo }; var obj1 = { a: 2, obj2: obj2 }; obj1.obj2.foo(); // 42 Implicitly Lost(隐式丢失) function foo() { console.log( this.a ); } var obj = { a: 2, foo: foo }; var bar = obj.foo; // function reference/alias! var a = "oops, global"; // `a` also property on global object bar(); // "oops, global"
bar は obj 上の foo を参照しますが、実際には foo を直接参照するのと同等であるため、デフォルトでグローバルにバインドされます。
function foo() { console.log( this.a ); } function doFoo(fn) { // `fn` is just another reference to `foo` fn(); // <-- call-site! } var obj = { a: 2, foo: foo }; var a = "oops, global"; // `a` also property on global object doFoo( obj.foo ); // "oops, global"