반응형
화살표 함수
- ES6(ES2015)부터 추가된 자바스크립트 함수 표현식의 간결한 문법
- function 키워드 대신 => 기호를 사용하여 짧고 직관적으로 함수 작성 가능
- this 바인딩 주의
- new 연산자로 인스턴스 생성 불가, new 생성자와 함께 호출할 수 없음
특징
1. this 바인딩이 없음 → 상위 스코프의 this를 사용함
- 기본 함수와 차이
- 일반 함수는 호출될 때마다 this가 그 함수에 맞게 새로 정해지는 반면 (동적 바인딩)
- 화살표 함수는 this를 자기 내부에서 새로 만들지 않고, "바깥쪽 함수" 또는 "바깥 스코프"의 this를 그대로 사용
- 언제 유용? 콜백 안에서 this 유지할 때!
화살표 함수의 this 특징
- 화살표 함수는 this를 만들지 않는다.
→ 자기 안에서 새로 바인딩하지 않음 - this는 바깥(선언된 위치)의 this를 그대로 사용한다.
→ 스코프 체인을 따라 올라감 - 객체 안에서 써도 객체를 가리키지 않는다.
→ 객체의 메서드로 사용하면 this는 window(전역) 일 수 있음 - 전역에서 선언되면 this는 window가 된다.
→ 브라우저 기준 - 그래서 객체의 속성을 참조할 때는 화살표 함수를 쓰면 안 될 수도 있다.
선언 위치에 따른 this가 가리키는 대상
✓ “화살표 함수는 this를 직접 만들지 않고, 자기가 태어난 환경의 this를 그대로 따라간다!”
1. 전역에서 선언 → window 또는 global
- 전역 스코프의 this는 브라우저에선 window를 가리킴.
const sayHi = () => {
console.log(this); // 브라우저: window, Node.js: global
};
sayHi();
2. 객체 안에서 화살표 함수 → this는 객체 ❌, 바깥 스코프 ✅
- 객체 ❌ → 바깥 스코프(this)
- 화살표 함수는 자기만의 this를 만들지 않음 (일반함수 자동으로 객체를 가리키지 않음)
그래서 객체 안이라고 해도, 화살표 함수의 this는 객체를 가리키지 않고 밖에서 물려받은 this를 그대로 씀 - 화살표 함수가 선언된 바깥 스코프의 this를 그대로 사용함
- 만약 바깥 스코프가 전역이라면 this는 window가 됨 (브라우저 기준)
const user = {
name: "ho",
sayHi: () => {
console.log(this.name); // undefined
}
};
user.sayHi(); // ❌ this는 user가 아님!
3. 함수 내부에 선언된 화살표 함수 → 바깥 함수의 this를 그대로 사용
- 함수의 this를 그대로 따름
- 함수 안에서 화살표 함수를 만들면, → 그 바깥 함수의 this를 그대로 따라감
- 바깥 함수가 어떤 객체의 메서드로 호출됐다면 → 화살표 함수 안의 this도 그 객체를 가리킴
- 이 덕분에 setTimeout, forEach 같은 콜백 안에서도→ this가 변하지 않고 유지됨
/*
여기서 this는 sayHi 함수의 this, 즉 user
화살표 함수는 그걸 그대로 가져다 씀
*/
const user = {
name: "ho",
sayHi: function () {
const inner = () => {
console.log(this.name); // ✅ "ho"
};
inner();
}
};
user.sayHi(); // "ho"
2. arguments 객체가 없음
- 일반 함수는 함수 내부에서 arguments라는 유사 배열 객체를 사용할 수 있어, 전달된 모든 인수를 사용할 수 있음
- 화살표 함수는 자기만의 arguments가 없음 → 대신 바깥쪽 함수의 arguments를 참조함
- 그래서, 만약 화살표 함수가 전역이나 함수 밖에서 쓰이면,
→ arguments가 없거나, 접근할 수 없어서 에러가 나거나 의도한 대로 실행되지 않을 수 있음
✓ “ 화살표 함수 안에서 arguments를 쓰면, 자기 것 말고 바깥 함수의 arguments를 대신 사용!”
function normalFunc() {
const arrow = () => {
console.log(arguments); // ✅ normalFunc의 arguments
};
arrow(1, 2, 3);
}
normalFunc("a", "b"); // arguments는 ["a", "b"]
// 시각적 흐름
normalFunc("a", "b")
│
├─ arguments → ["a", "b"]
│
└─ arrow(1, 2, 3)
│
└─ 화살표 함수라 자기 arguments x
→ normalFunc의 arguments 사용 o
/*
- 단계별 설명-
1. normalFunc("a", "b")를 호출함
→ 이 함수의 arguments는 ["a", "b"]
2. 함수 안에 화살표 함수 arrow가 있음
→ arrow(1, 2, 3)처럼 3개의 인수를 넘겨 호출했지만…
3. 화살표 함수는 자기만의 arguments를 만들지 않기 때문에,
→ arrow() 안에서 arguments를 쓰면
→ 자기를 감싸고 있는 normalFunc의 arguments, 즉 ["a", "b"]가 출력됨
4. 그래서 결과는 ["a", "b"]가 출력
→ console 출력 결과 Arguments(2) 0: "a", 1:"b"
→ arrow()에 넘긴 1, 2, 3은 무시됨
*/
3. new 키워드로 사용할 수 없음 (생성자 함수 ❌)
- 일반 함수는 new로 객체를 생성할 수 있지만,
- 화살표 함수는 생성자 함수가 아니므로 new로 호출하면 에러
- 생성자 역할이 필요하다면 function 또는 class를 써야 함
const Person = (name) => {
this.name = name;
};
const p = new Person("hp"); // ❌ TypeError
4. prototype 속성이 없음
- 일반 함수는 prototype 속성을 가지며, 이를 기반으로 상속이 가능
- 화살표 함수는 prototype 속성이 없음 → 프로토타입 기반 객체 생성이나 상속 불가
5. 익명 함수 로만 사용됨
- 화살표 함수는 항상 변수에 할당하거나, 콜백으로 전달해서 사용해야 함
const add = (a, b) => a + b;
[1, 2, 3].forEach(v => console.log(v));
문법
- 화살표 함수 정의가 한 줄인 경우 : {} 와 return 생략 가능
- 파라미터가 1개인 경우 : () 생략 가능
- 객체 리턴할 때 주의 : 객체를 바로 리턴하려면 소괄호로 감싸야함
// 기본 문법
const 함수이름 = (매개변수) => {
실행할 코드;
return 결과값;
};
// 한 줄일때 표현 ({}와 return 생략 가능)
const func = (a) => a+2
// 파라미터(매개변수)가 1개 인 경우 () 생략 가능
const func = a => ()
// 다른 선언 방법
const func = x => y => z => `${x], ${y}, ${z}`
// 위 함수를 일반 함수로 표현하면 아래와 같음
function func(x){
return function(y){
return function(z){
return `${x], ${y}, ${z}`
}
}
}
func(2)(4)(8)
// (key,value) object 반환 시 소괄호 사용
let get = param => ({sport:'soccer'})
// bool
(매개변수) => {
} bool 표현식 || boolean 값이 거짓을 떄 실행할 문장
화살표 함수와 일반함수의 차이
항목 | 화살표 함수 | 일반함수 |
this 바인딩 | ❌ 없음 (상위 스코프를 사용함) | ✅ 함수 내부에서 바인딩됨 |
생성자 함수 사용 | ❌ 불가능 | ✅ 가능 (new 사용 가능) |
arguments 객체 사용 | ❌ 불가능 | ✅ 가능 |
간결한 문법 | ✅ 매우 간결 | ❌ 다소 장황함 |
구분 | 화살표 함수 | 일반 함수 |
this | 외부 스코프 상속 - 자신이 this를 가지지 않음 자신이 정의 된 외부 스코프의 this를 그대로 사용 - this를 묶는 것이 가능 - property에 화살표 함수를 연결하면 화살표 함수 블록에서 this가 인스턴스를 참조하지 못함 - 내부 콜백에서 this가 바뀌는 문제를 피하고 싶을때, 화살표 함수를 사용 |
호출 방식에 따라 결정 호출된 문맥에 따라 "this"가 바뀜 |
arguments | 사용 불가 | 사용 가능 |
생성자 (new) | 불가능 | 가능 |
메서드 정의에 적합 | ❌ | ⭕ |
const box = document.querySelector('.box')
// 일반함수에서 this
box.addEventListener('click', function(){
this.style.color="red" // box를 가리킴
})
// 화살표 함수에서 this
/*
- 화살표 함수는 자신만의 this를 가지지 않음
- 대신 함수가 정의된 시점의 this(상위 스코프의 this) 를 그대로 상속받음
- 해당 this의 상위스코피는 window(브라우저 전역 객체)
*/
box.addEventListener("click", ()=>{
this.style.color='red' // this가 Window 객체로 설정되어 property ~~ undefined 에러 발생
})
// 화살표 this의 적절한 활용
/*
- 여기서 addEventListener는 일반함수로 등록되어 this는 box를 가리킴
- setTimeout 함수를 화살표 홤수로 사용하여 외부의 this를 그대로 가져옴
(※setTimeout은 비동기적으로 실행되는 함수이기 때문에
여기서 setTimeout(function(){..} 처럼 일반함수를 사용했다면, this는 window를 가리킴
!" 내부 콜백에서 this가 바뀌는 문제를 피하고 싶을때, 화살표 함수를 사용 "
function()은 this를 "호출하는 방식"에 따라 정함
- 첫 번째 function()은 addEventListener가 box 기준으로 호출해줌
→ 그래서 this === box
- 두 번째 function()은 1초 뒤에 setTimeout이 직접 호출
→ 이때 **일반 함수는 전역 객체(window)**를 this로 바꿈
→ 따라서 this === window
- setTimeout(함수, 시간)은 1초 뒤에 함수만 따로 전역 컨텍스트에서 호출함
- 이때 일반 함수는 주변 문맥을 기억하지 못하고, 자기만의 this를 다시 설정해버림 → window
*/
box.addEventListener("click", function () {
this.style.color = "red";
setTimeout(() => {
this.style.color = "black"; // 이 this는 상위스코프에 상속되어 box를 가리켜 정상 작동
}, 1000);
});
[javascipt] 일반함수와 화살표 함수에서의 this
화살표 함수와 일반함수의 this 비교일반 함수는 호출 방식에 따라 this가 달라짐.화살표 함수는 정의된 위치의 this를 그대로 가짐.따라서 화살표 함수는 보통 this를 고정해서 사용하고 싶을 때 사
u-pub.tistory.com
화살표 함수에서 arguments
- arguments 객체는 함수 내부에서 접근할 수 있는 배열 객체로 해당 함수에 전달돼 인수의 값을 담고 있음
- 일반함수에서 arguments는 배열 표기법을 사용하여 해당 인수에 접근 가능
- 화살표 함수에서 arguments는 스프레드 문법을 활용하여 해당 인수에 접근 가능
// 일반함수의 arguments 활용
function test(){
console.log(arguments[0])
}
test(1,2) // => 1
// 화살표 함수의 arguments의 잘못된 사용
const show=()=>{
const name = arguments[0]
console.log(`name : ${name}`)
}
show('j','a','b') // 오류 :arguments is not defined
// 화살표 함수의 arguments 적절한 사용(스프레드 문법 활용)
const show2 = (...args) => {
const name = args[0]
console.log(`name : ${name}`)
}
show2('a','b','c') // name:a
반응형
'JS > Javascript' 카테고리의 다른 글
[javascript] 클로저 (Closure) (0) | 2023.02.25 |
---|---|
[함수] 중첩함수 (0) | 2023.02.25 |
[Javascript] 변수 (0) | 2023.02.04 |
[javascript] 함수-1 / 함수의 기초 이해, 선언 방식 ... (0) | 2023.02.04 |
[Javascript] 매개변수(parameter)와 전달인자(argument) (0) | 2023.02.04 |