Javascript this keyward
This 란?
두 값이 모두 undefined 가 나온다. 이유를 알아보자.
이번 상황의 this는 좀 다르다. method 안에 표현형 함수를 정의 했고 그 함수 안에 this 를 사용했다.
This 는 모든 실행 컨텍스트(모든 함수)에 대해 생성되는 특별한 값이다.
그리고 this 키워드가 사용된 함수의 "owner" 의 값을 가진다
this는 값이 똑같지 않다. this 의 값은 함수가 어떻게 호출됬는지에 따른다. 그리고 this의 값은 오직 함수가 실제로 호출될 때만 할당된다.
Method => this 는 method를 소유한 객체를 가르킨다.
Simple function call => this = undefined (엄격 모드에서만 해당된다. 아닐 경우 전역 객체인 window 의 값을 가져온다.)
Arrow function => this = lexical this 이다. 즉, 자신을 둘러싼 환경의 this 를 그대로 승계받는다.
Event Listener = > this => handler 함수가 붙어 있는 DOM 요소이다.
new,call,apply,bind => later course..
this 는 사용하고 있는 함수를 절대 가르키지 않는다.
또한 함수의 variable environment를 절대 가르키지 않는다.
1 2 3 4 5 6 7 8 9 10 11 12 | const jonas = { firstName: 'Jonas', year: 1991, calcAge: function () { console.log(this); console.log(2037 - this.year); }, greet: () => console.log(`Hey ${this.firstName}`), }; jonas.greet(); //Hey undefined console.log(this.firstName); //undefined | cs |
예제와 함께 알아보자
greet 함수는 arrow function으로 arrow function 은 자기 소유의 this 를 갖지 못한다. 단순하게 하자면 함수 스코프의 영향을 받지 않고 주위 코드에서 쓰이는 this 와 같은 값을 가진다. 참고로 객체의 코드 블럭은 block scoping이 아니다. 따라서 greet 함수의 this는 window 전역 객체를 가르킨다. 따라서 window.firstName이 된다. 이때 var을 잘 사용하지 않는 이유가 나온다. 만약 var firstName을 객체 위에서 선언했더라면 firstName은 window에 property 로 선언되고 이는 찾기 힘든 오류가 생성된다. 하지만 let , const는 window에 특성으로 선언되지 않으므로 안심하고 사용할 수 있다.
this.firstName이 undefined가 나오는 이유는 마찬가지로 여기서의 this 는 window를 가르키고 window 에는 firstName 이라는 property가 없으므로 window.firstName = undefined를 가져오게 된다.
이런 오류를 예방하기 위해선 단순히 arrow function을 method로 사용하지 않으면 해결된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | const jonas = { firstName: 'Jonas', year: 1991, calcAge: function () { console.log(this); const isMillenial = function () { console.log(this); }; isMillenial(); }, }; jonas.calcAge(); | cs |
이번 상황의 this는 좀 다르다. method 안에 표현형 함수를 정의 했고 그 함수 안에 this 를 사용했다.
결과는 undefined 이다. 일반 상황의 함수에서 this 를 사용하면 undefined 이다. 따라서 매쏘드 안에 있더라도 this 는 일반 상황의 함수안에 있으므로 undefined 의 값이 나오게 된다.
이를 해결하기 위한 방안은 2가지가 있다.
첫번째는 추가적인 변수를 활용하는 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | const jonas = { firstName: 'Jonas', year: 1991, calcAge: function () { console.log(this); const self = this; const isMillenial = function () { console.log(self); }; isMillenial(); }, }; jonas.calcAge(); | cs |
위 와 다르게 코드 const self = this; 를 추가했다. this는 동적인 변수이다. 그러므로 매쏘드 안에의 this 는 올바르게 객체 jonas를 가르킨다. 하지만 this가 일반 함수에서 사용 되면 undefined를 가지게 된다. 따라서 매쏘드 안에서의 this 값을 self 에 저장하고 일반 함수 안에서는 self 를 사용하면 해결할 수 있는 문제이다.
두번째는 arrow function을 사용하는 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | const jonas = { firstName: 'Jonas', year: 1991, calcAge: function () { console.log(this); const self = this; const isMillenial = () => { console.log(this); }; isMillenial(); }, }; jonas.calcAge(); | cs |
위에선 isMillenial 함수는 일반 함수로 선언하였지만 지금의 함수는 arrow function 을 이용하였다. 앞서 말했듯 arrow function을 이용하면 오해의 표현일 순 있지만 함수를 쓰지 않은 것처럼 this를 사용할 수 있다. (=arrow function의 parent scope를 따른다와 같은 의미이다.)따라서 매쏘드 안에 있는 this 가 되므로 arrow function 을 이용하여 문제를 해결 할 수 있다.
이번엔 arguments 키워드에 대해 알아보자!
arguments 키워드는 함수의 인자를 가져오는 역할을 한다. 여러 인수들이 있으면 이를 배열 형태로 저장하므로 여러 인자가 있을때 유리하게 사용 할 수 있다.
this 키워드 와는 다르게 일반 함수 형태에서만 사용할 수 있고 arrow 함수에서는 사용이 불가능하다.
1 2 3 4 5 6 7 8 9 10 11 12 | const add1 = function (a, b) { console.log(arguments); return a + b; }; add1(2, 5); add1(2, 5, 8, 10); var addArrow = (a, b) => { console.log(arguments); return a + b; }; addArrow(2, 5); | cs |
함수 선언식에서는 arguments 키워드가 정상 작동하지만 아래의 화살표 함수에서는 오류가 발생한다.
댓글
댓글 쓰기