this란 객체를 참조하는 키워드다.
하지만 다른 언어와 다르게 런타임 바인딩 되기때문에 this의 값은 함수를 호출한 위치에서 결정된다.
[기본바인딩]
function foo() {
console.log(this);
}
foo(); //// window
기본바인딩은 global적으로 바인딩이 되는것을 말하며 브라우저 상에서는 window 객체를 가르킨다.
[암시적 바인딩]
window.a = 'window';
function foo() {
console.log(this.a);
}
const obj = {
a:1,
foo: foo
}
obj.foo() // 1
foo() // window
함수가 f호출되는 위치에서 this가 바인딩 되어진다.
위의 경우 this가 { a: 1, foo: foo } 객체에 바인딩 되면서 a를 가져오게 된다.
만약 foo()를 호출하면 this는 기본바인딩이 되면서 a를 알수없으므로 'window'가 된다.
function foo() {
console.log(this.a);
}
const obj = {
a:1,
foo: foo
}
//reference case 1
const foo2 = obj.foo;
foo2(); // undefined
//callback case 2
setTimeout ( obj.foo , 100 ); // undefined
위처럼 암시적 바인딩을 하게되는경우 함수호출 위치에 따라서 런타임 바인딩이 되기때문에 원하는 값을 얻지 못하는 경우가 있다.
[명시적 바인딩]
function foo() {
console.log(this.a);
}
const obj = { a: 1 };
foo.call(obj); // 1
call, apply, bind함수를 사용하여 this를 원하는 대상에 바인딩 시켜준다.
foo함수의 this를 obj에 바인딩 시킨다.
function add(a, b) {
return a + b;
}
add.call(null, 1, 2); // 3
add.apply(null, [1, 2]); // 3
두 함수 모두 첫번째 인자에는 this로 사용할(this가 가리킬) 객체를 넣어준다. 이때 null 이나 undefined를 넣으면 자동적으로 this는 global객체를 가리킨다.
call은 함수에 사용될 인자들을 , 로 구분지어 넣어주고, apply는 인자들을 배열형태로 넣어준다.
function foo() {
console.log(this.a);
}
const obj = {
a:1,
foo: foo
}
const foo2 = obj.foo.bind(obj);
const foo3 = foo2.bind({a: 4});
foo2(); //1
foo3(); //1
call과 apply의 경우 함수의 실행값을 반환하는 반면 bind는 this가 새롭게 바인딩한 함수(원본 함수의 복제본)를 반환한다.
bind를 통해 생성된 함수의 this는 최초의 바인딩된 객체로 고정된다.
다시 명시적으로 바인딩해도 this가 바뀌지 않는 것을 확인할 수 있다.
const globalThis = this;
const arrowThis = () => this;
arrowThis() === globalThis // true
화살표 함수에는 this가 없다. 대신 화살표 함수를 둘러싸는 렉시컬 범위(lexical scope)의 this가 사용된다. 바로 바깥 범위(바로 상위)에서 this를 찾는다. 따라서 예시에서 this는 바로 상위인 글로벌을 가리킨다.
[new를 통한 바인딩]
function Foo() {
console.log(this);
}
new Foo(); // Foo
new를 통해 생성하게되면 this는 새로 생성된 객체를 가르키게 된다.
끝맺음
this는 위 4가지 방법으로 바인딩 된다.
최대한 헷갈리지 않게 하기위해서 쉽게 작성했다. 어렵게 이해하지말고 최대한 받아들인다는 생각을 했으면 좋겠다.
도움 받은곳
https://github.com/getify/You-Dont-Know-JS
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this
'갬발자의 프로그래밍 > Javascript' 카테고리의 다른 글
[Javascript] 프로토타입 언어 : prototype 과 객체 생성 (0) | 2021.02.22 |
---|---|
유용팁 (0) | 2020.03.26 |
closure(클로저) (0) | 2020.01.13 |
재귀함수 (0) | 2020.01.10 |
배열 (0) | 2020.01.09 |
댓글