티스토리 뷰
global execute context 에서 실행될 때
a=1 | Global |
var a = 1 | Global |
let a =1 | Script |
const a =1 | Script |
function execute context 에서 실행될 때
a=1 | Global |
var a = 1 | Local |
let a =1 | Local |
const a =1 | Local |
*let 과 const 는 함수 안에서가 아니라 block 안에서 local로 들어간다.
Closure(클로져)
- self-invocation을 한 함수의 리턴값을 변수에 할당한다.
- 리턴을 익명함수로 선언하면 변수는 그 익명함수를 리턴받게 된다.
- 변수명에 함수를 실행하는 ()연산을 하면 리턴으로 받은 함수만 실행되고, self-invocation이 되었던 함수는 메모리에 상주한 상태로 대기하게 된다.
- 부모 함수의 실행상태를 대기시키고 닫는다(폐쇄)는 의미로 클로져라고 부른다.
ex)
let getMyNum = (function (){
const myNum = 10; // 외부에서 접근 및 변경 절대 불가
return function(num){
return myNum * (Math.floor(Math.random()*num)+1)
};
})(); //내부에서 익명함수 실행
console.log(getMyNum(100));
디버거로 클로저 이해하기
TIP: 참고로 개발자 도구에서 디버거를 사용하려면 브레이크 포인트를 걸고 f5(새로고침)을 해줘야 합니다.
- function 이라고 체크한 버튼은 누를 시 해당 스텝에서 function 내부로 들어가 작동을 확인할 수 있습니다.
- Next 라고 표시한 버튼은 말 그대로 다음 function 스텝으로 넘어가는 것입니다.(함수 호출 시)
- 어디에서 호출했느냐에 따라서 유효범위가 달라진다면 그것을 dynamic scope(동적 스코프)라고 부릅니다. 하지만 JS는 동적 스코프가 아닌 정적 스코프를 채택하고 있습니다.
<script> let l0 = "l0"; //전역변수 선언 function fn1() { let l1 = "l1"; console.log(l0, l1); // script l0, 지역 l1 fn2(); } function fn2() { let l2 = "l2"; //l1이 정의되어 있지 않다고 뜬다 -> l1 에 접근할 수 없다. console.log(l0, l1, l2); } fn1(); </script>
- 그렇기 때문에 fn2()를 호출한 곳에 l1이 지역변수로 선언되어 있더라도 scope chain이 없기때문에 fn2() 내부에서 l1에 접근할 수 없게 됩니다. 그렇다면 fn1함수 내부에 fn2를 옮기면 어떻게 될까요?
<script> let l0 = "l0"; //전역변수 선언 function fn1() { function fn2() { let l2 = "l2"; console.log(l0, l1, l2); // script: l0, Closure(fn1) l1 , local l2 } let l1 = "l1"; console.log(l0, l1); fn2(); } fn1(); </script>
- 클로저 라는 것이 local 과 Global 사이에 생겼습니다. 그리고 소괄호의 안에는 함수의 이름이 적혀있습니다. fn1
- 클로저를 눌러보면 l1 : "l1" 해당 함수의 로컬이 저장되어 있습니다. 여기서 클로저란 호출된 함수의 부모함수의 스코프 혹은 변수들을 동봉해서 가지고 있기 때문에 언제든지 접근할 수 있다는 의미 입니다. 이렇게 되면 함수는 오류없이 정상적으로 작동하게 됩니다. script: l0, Closure(fn1) l1 , local l2
- 이처럼 어떤 호출된 함수의 유효범위는 어디서 실행되느냐(동적 스코프 채택)의 문제가 아니라 어디서 정의(정적 스코프 채택)되었느냐에 따라서 달라집니다.
- JS는 static scope or lexical scope(정적 스코프)를 채택하고 있습니다.
▶결론: 부모 함수 안에서 자식 함수를 선언하면 자식함수를 어디에서 호출하더라도 자식함수 안에서 부모함수의 변수에 접근할 수 있다(클로저).
활용예시
<script>
function 더하기함수공장(초기값) {
function 덧셈(숫자) {
return 초기값 + 숫자;
}
return 덧셈;
}
let 더하기1 = 더하기함수공장(1);
console.log(더하기1(1)); //output: 2
console.log(더하기1(2)); //output: 3
let 더하기2 = 더하기함수공장(2);
console.log(더하기2(1)); //output: 3
console.log(더하기2(2)); //output: 4
</script>
all ref: https://www.youtube.com/watch?v=bwwaSwf7vkE
'Frontend > JavaScript' 카테고리의 다른 글
[생활코딩][웹브라우저JS]- Node 객체, Node객체 API (0) | 2022.02.06 |
---|---|
[생활코딩][웹브라우저JS]- Element객체, 관련 API (0) | 2022.02.03 |
[생활코딩][웹브라우저JS]- HTMLElement, Dom Tree (0) | 2022.01.29 |
[생활코딩][웹브라우저JS]- 창 제어(window객체) (0) | 2022.01.27 |
[생활코딩][웹브라우저JS]- Navigator 객체 (0) | 2022.01.27 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- reactAPI
- Prittier
- grid flex
- nvm 설치순서
- D 플래그
- getServerSideProps
- aspect-ratio
- fs모듈 넥스트
- is()
- 원티드 프리온보딩 FE 챌린지
- text input pattern
- 프리렌더링확인법
- getStaticPaths
- 타입스크립트 DT
- 원티드 프리온보딩 프론트엔드 챌린지 3일차
- tilde caret
- 부트캠프항해
- 원티드 3월 프론트엔드 챌린지
- ~ ^
- && 셸 명령어
- 프리온보딩 프론트엔드 챌린지 3월
- float 레이아웃
- 타입스크립트 장점
- 항해99추천비추천
- 틸드와 캐럿
- 항해99프론트후기
- 원티드 FE 프리온보딩 챌린지
- nvm경로 오류
- 항해99프론트
- 형제 요소 선택자
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
글 보관함