어딜 가나 물어보는 ES6 문법 확인해 보면 전부 화살표 함수를 사용하고 있으며 예시에 this란 아이도 굉장히 많이 보이는데 그러한 모든 것들을 이해하기 위해 this를 짚고 넘어가자
this 값은 실행 컨텍스트(global, function 또는 eval)의 프로퍼티는 비엄격 모드에서 항상 객체를 참조하며, 엄격 모드에서는 어떠한 값이든 될 수 있다고 공식에서 설명한다.
어떠한 값도 될 수 있는 this의 값은 함수를 호출한 방법에 의해 결정되기에 많은 사람들이 어려워했다. 이를 위해 ES5에서는 함수를 어떻게 호출했는지 상관하지 않고 this값을 설정할 수 있는 bind 메서드를 도입했고 ES6에서는 this 바인딩을 제공하지 않는 화살표 함수를 추가했다.
const test = {
prop: 42,
func: function() {
return this.prop;
},
};
console.log(test.func());
// expected output: 42
공식에 나와있는 예시이다 이렇게 보면 test.func()의 this는 test를 바로보고 있다
위에 공식 설명에서 나왔듯이 선언된 객체의 값을 바로보고 있는 것이다 근데 만약 저 객체를
const test = {
prop: 42,
func: function() {
let testArr = [1,2,3,4];
testArr.forEach(function(item) {
console.log(item, this.prop);
});
},
};
console.log(test.func());
// expected output: 1, undefiend
// expected output: 2, undefiend
// expected output: 3, undefiend
// expected output: 4, undefiend
위처럼 바꾸면 this.prop이 갑자기 undefined로 바뀐다 도대체 어디서 문제 였을까 그건 바로
forEach라는 새로운 메서드가 실행되면서 forEach내부에서 this가 전역 객체를 자동으로 바인딩을
해버리는 것이다 그렇담 forEach 실행 함수를 화살표 함수로 바꿔 준다면?
const test = {
prop: 42,
func: function() {
let testArr = [1,2,3,4];
testArr.forEach((item) => {
console.log(item, this.prop);
});
},
};
console.log(test.func());
// expected output: 1, 42
// expected output: 2, 42
// expected output: 3, 42
// expected output: 4, 42
이렇게 this.prop가 우리가 원하는 데로 test의 prop를 바라보고 있는 것을 확인 할 수 있다
그러니까 화살표 함수(arrow 문법)을 사용하면 this를 바인딩 하지 않는다는 걸 알 수 있다(this를 동
적으로 바인딩하지 않는다는 말과 같다) 그러니 화살표 함수를 사용하면 this를 선언된 scope의 this
로 사용 할 수 있는 장점이 생긴다.
지금까지 예시를 통해 그냥 함수와 화살표 함수를 사용할 때 어떻게 this가 바인딩되는지 정리해 봤다 그렇다면 화살표 함수 모양에 대한 의문을 한 번 가져보자 어떻게 이런 모양의 함수가 나오는 가
- 일반 함수는 전역적이며, 전체가 다 호이스팅 되므로 호출의 위치와 구현의 위치 간에 연관관계가 없다. 또한, 재사용될 기능에 주로 사용된다.
- 익명 함수는 선언 부만 호이스팅 되며 호출의 위치와 구현의 위치 간에 순서가 알맞아야 하고, 한 번만 사용하는 기능에 사용된다.
const jeon = function(n) {
console.log(n);
}
jeon('test');
=> output : test;
- 이런 구조의 익명 함수가 javascript ES6화살표 함수를 만나면서 모양이 바뀐다 그게 바로 우리가 흔히 사용하고 있는 이런 모양이고 자바스크립트 익명 함수는 함수명 대신 변수명에 함수 코드를 저장하는 구현 방식이다.
const jeon = (n) => {
console.log(n);
}
- 근데 알아야 할 것은 javascript에서는 이런 구조를 꼭 재사용하지 않을 것이라서 사용하는 것은 아니다 더 간결하고 읽기 쉽게 코드를 짤 수 있다는 이점도 제공한다 또한 이런 익명 함수는 호출 시 변수명을 사용해서 호출하면 된다.
- 한 가지 특징이 있다면 호이스팅이 지원되지 않는다.
원래함수
jeon('aa'); // output : aa
function jeon(n) {
console.log(n);
}
// jeon이란 함수는 호이스팅 되고 위에 함수 호출은 잘 실행된다.
익명함수
jeon('aa'); // output : 에러 발생
const jeon = (n) => {
console.log(n);
}
또한 공식에서 화살표 함수를 call(), bind(), apply()를 사용해 호출할 때 this의 값을 정해주더라도 무시한다고 하며 사용할 매개변수를 정해주는 건 문제없지만, 첫 번째 매개변수(thisArg)는 null을 지정해야 한다고 한다.
여기서 o.f에 independent 함수를 넣어준 것과 console.log에서 찍히는 값을 유의하자
var o = {prop: 37};
function independent() {
return this.prop;
}
o.f = independent;
console.log(o.f()); // logs 37
this 바인딩은 호출 시 가장 근접한 멤버 대상에 영향을 받는다 그래서 함수가 동작할 때는 함수 내부의 this는 o를 나타내며 오직 o의 멤버 f로부터 호출된 것만이 중요하다는 것을 보여준다.
이렇게 this에 대해 정리해 보았는데 항상 문법에 대해 공부하다 보면 내가 정말 얕게 알고 있었고 배울 게 정말 많다고 느낀다. 이 글을 보시는 분들에게 많은 도움이 되길 바란다.
'개발 > JavaScript' 카테고리의 다른 글
[JavaScript] parameter vs argument (0) | 2023.02.04 |
---|---|
[JavaScript] 날짜 비교 (0) | 2023.01.29 |
[JavaScript] ES6 문법 (2) | 2022.11.11 |
[JavaScript] ES5 문법 (0) | 2022.11.10 |
[JavaScript] 문자열 내에 특정 문자 제거(replace,replaceAll) (0) | 2022.10.28 |
댓글