먼저 예시를 살펴보겠습니다
function foo() { console.log( this.a ); } var obj = { a: 2, foo: foo }; obj.foo(); // 2
이것은 obj를 가리킵니다. foo가 실행될 때 호출 사이트(호출 시 범위로 이해될 수 있음)가 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"