-
화살표함수와 일반함수 차이점& 호이스팅html.css.js/javaScript 2024. 6. 24. 22:59
화살표 함수 (Arrow Function)
렉시컬 스코프
- 화살표 함수는 자신이 정의된 위치에서의 this 값을 상속받습니다.
- 따라서 화살표 함수 내에서 this를 사용할 때, 이는 화살표 함수가 정의된 외부 스코프의 this와 동일합니다.
문법적 특징
- function 키워드를 사용하지 않고, 더 간결한 문법을 사용합니다.
const myArrowFunction = () => { console.log(this); }
일반 함수 (Regular Function)
동적 스코프
- 일반 함수의 경우, this는 함수가 호출될 때 결정됩니다. 이는 해당 함수가 어떻게 호출되었는지에 따라 달라집니다.
문법적 특징
- function 키워드를 사용하여 정의합니다.
function myRegularFunction() { console.log(this); }
차이점 예제
다음은 두 함수 간의 this 처리 차이를 보여주는 예제입니다.
예제 코드:
javascript코드 복사 const obj = { name: '메가커피', arrowFunc: () => { console.log('Arrow Function:', this.name); }, regularFunc: function() { console.log('Regular Function:', this.name); } }; obj.arrowFunc(); // Arrow Function: undefined (또는 전역 객체의 name 속성 값) obj.regularFunc(); // Regular Function: Object
- 화살표 함수: obj.arrowFunc가 호출될 때, 화살표 함수는 this를 obj가 아닌 상위 스코프(전역 스코프)에서 가져옵니다. 전역 스코프에서는 name 속성이 정의되지 않았기 때문에 undefined가 출력됩니다.
- 일반 함수: obj.regularFunc가 호출될 때, this는 호출 객체인 obj를 참조합니다. 따라서 this.name은 '메가커피'가 되어 출력됩니다.
- 화살표 함수는 정의된 위치의 상위 스코프의 this 값을 사용하여 일관된 this 바인딩을 제공합니다.
- 일반 함수는 호출 시점에 this가 결정되어 더 유연하지만, 예상치 못한 this 값이 참조될 수 있습니다.
이 차이점은 특히 이벤트 핸들러나 콜백 함수에서 매우 중요한데, 이러한 상황에서 this 바인딩이 중요한 역할을 하기 때문입니다.
호이스팅이란?
호이스팅(Hoisting)은 JavaScript에서 함수와 변수의 선언이 해당 스코프의 최상위로 끌어올려지는 동작을 의미합니다.
즉, 코드가 실제로 실행되기 전에 변수와 함수의 선언이 위로 이동한 것처럼 동작합니다. 그러나 변수 초기화는 호이스팅되지 않습니다.호이스팅은 마치 "여기 선언된 모든 변수를 먼저 알아두고, 나중에 값을 채워넣자!"라고 말하는 것과 같아요.
즉, 변수를 선언하는 부분을 코드의 맨 위로 끌어올리는 것을 말해요.변수 호이스팅
🫵🏻 변수 선언은 호이스팅되지만, 초기화는 호이스팅되지 않습니다. 따라서 변수를 선언하기 전에 참조하면 undefined가 반환됩니다.
예를 들어, 아래와 같은 코드가 있다고 해볼게요.
console.log(myVar); // 무엇이 출력될까요? var myVar = 5;
우리가 예상하기에 myVar가 5로 되어 있으니 5가 출력될 것 같죠? 하지만 실제로는 undefined가 출력돼요. 왜냐하면 자바스크립트는 코드를 이렇게 바꿔서 실행하기 때문이에요:
var myVar; console.log(myVar); // undefined가 출력돼요 myVar = 5;
즉, var myVar라는 선언 부분이 맨 위로 올라간 거예요.
함수 호이스팅
함수 선언은 전체가 호이스팅됩니다. 따라서 함수 선언을 코드에서 호출하기 전에 사용할 수 있습니다.
예제:
myFunction(); // "Hello, world!" function myFunction() { console.log("Hello, world!"); }
호이스팅된 상태:
function myFunction() { console.log("Hello, world!"); } myFunction(); // "Hello, world!"
함수 표현식과 호이스팅
함수 표현식은 변수 선언과 같이 호이스팅되지만, 함수 정의는 호이스팅되지 않습니다. 따라서 함수 표현식을 선언하기 전에 호출하려고 하면 undefined로 인해 오류가 발생합니다.
예제:
myFunction(); // TypeError: myFunction is not a function var myFunction = function() { console.log("Hello, world!"); };
호이스팅된 상태:
var myFunction; myFunction(); // TypeError: myFunction is not a function myFunction = function() { console.log("Hello, world!"); }
let과 const의 호이스팅
let과 const로 선언된 변수도 호이스팅되지만, 초기화는 선언 전에 접근할 수 없다는 점에서 var와 다릅니다. 이를 "Temporal Dead Zone"이라고 합니다.
예제:
console.log(myLetVar); // ReferenceError: Cannot access 'myLetVar' before initialization let myLetVar = 5; console.log(myConstVar); // ReferenceError: Cannot access 'myConstVar' before initialization const myConstVar = 10;
- var로 선언된 변수는 호이스팅되며 초기화 전에는 undefined로 평가됩니다.
- 함수 선언은 호이스팅되어 선언 전에 호출이 가능합니다.
- 함수 표현식은 변수의 호이스팅 규칙을 따르며 선언 전에 호출할 수 없습니다.
- let과 const는 호이스팅되지만, 초기화 전에 접근할 수 없으며 이를 "Temporal Dead Zone"이라고 합니다.
결론
용어
- 스코프: 변수가 어디서 유효한지를 결정하는 범위입니다.
- 클로저: 함수가 생성될 때 그 함수가 속해 있던 스코프를 기억하는 것. 이를 통해 함수가 종료된 후에도 그 스코프에 있는 변수들을 사용할 수 있습니다.
화살표함수와 일반함수의 차이점?
화살표함수(렉시컬 스코프 또는 정적 스코프)
- 함수를 호출하는 위치에 관계없이 함수가 정의된 위치에서의 변수 환경이 사용됨
- 예측 가능성과 이해의 용이성을 위해 렉시컬 스코핑을 채택하고 있음
- 코드의 가독성을 높이고, 디버깅과 유지보수를 쉽게 만들어주는 중요한 개념입니다. 이를 이해하면 함수와 변수를 효과적으로 사용할 수 있고, 복잡한 코드에서도 변수 유효 범위를 쉽게 파악할 수 있습니다.
일반함수(동적 스코프)
- 동적 스코핑에서는 함수 호출 시점에서의 변수 환경이 사용됨
function makeToyBox() { let toy = "Action Figure"; // 상자 안에 장난감이 있습니다. return function() { return toy; // 상자 안의 장난감을 가져올 수 있습니다. }; }
이처럼 클로저는 함수가 생성될 때의 스코프(상자 안의 내용물)를 기억하고, 나중에 그 스코프에 접근할 수 있게 해줍니다. 이렇게 하면, 함수가 실행된 이후에도 변수를 계속 사용할 수 있습니다.
클로저는 "함수가 만들어질 때, 그 함수가 속해있던 환경(상자 안의 내용물)을 기억하는 것"입니다.
이렇게 기억된 환경은 함수가 실행된 후에도 접근할 수 있습니다- this 처리 차이
화살표함수와 일반함수의 가장 큰 차이점은
this을 어디에서 불러오냐? 이다.
(this는 함수가 가리키는 것을 말함)
const obj = { name: '메가커피', arrowFunc: () => { console.log('Arrow Function:', this.name); }, regularFunc: function() { console.log('Regular Function:', this.name); } }; obj.arrowFunc(); // Arrow Function: undefined (또는 전역 객체의 name 속성 값) obj.regularFunc(); // Regular Function: Object
화살표함수에서는 항상 외부스코프에서 this를 호출하기 때문에 undefined가 출력됨
(외부 스코프에서는 name을 지정하지 않았기 때문)
일반함수는 이와 달리 호출할 때 결정되는데 obj의 일반함수를 호출하므로 obj에 있는 name인 메가커피가 출력된다.
화살표함수
장점 : 화살표함수는 자기가 만들어진 곳을 기억하기 때문에 항상 this가 같다.
(우리엄마가 나를 낳으셨다. 나를 낳으신건 우리 엄마이기 때문에 변할 수가 없는것⇒그래서 this가 바뀌지 않음)
일반함수
⇒ 호출시에 this가 결정되는데 누가 호출하냐에 따라서 달라짐
단점
⇒ 일반 함수는 상황에 따라 행동이 달라질 수 있음
⇒ 그래서 이벤트를 처리할 때 어떤 함수를 쓰느냐에 따라 결과가 달라질 수 있다!!!
결론 : 화살표 함수는 일관되게 행동하고,일반 함수는 상황에 따라 다르게 행동
호이스팅이란?
함수 호이스팅
함수 선언은 전체가 호이스팅됩니다. 따라서 함수 선언을 코드에서 호출하기 전에 사용할 수 있습니다.
함수 표현식과 호이스팅
함수 표현식은 변수 선언과 같이 호이스팅되지만, 함수 정의는 호이스팅되지 않습니다. 따라서 함수 표현식을 선언하기 전에 호출하려고 하면 undefined로 인해 오류가 발생합니다.
변수 호이스팅
- var: "나는 변수를 만들었어! 하지만 아직 값을 넣지 않았어." 그래서 처음에는 undefined라고 해요.
- let과 const : 변수는 먼저 기억해두지만, 값을 넣기 전에는 사용할 수 없다.⇒"Temporal Dead Zone"