원시자료형
number, string, boolean, undefined, null
- 변수에
value
가 담긴다.- 데이터 공간 한칸에 하나의 데이터만 넣을 수 있다.
참조자료형
array, object, function
- 데이터는
heap
에 저장되고, 변수에는보관함의 주소
가 담긴다.- 데이터 저장소(heap)의 크기가
동적(dynamic)
으로 변한다.- 변수의 주소를
참조
하여 실제 변수가 있는 장소에 데이터가 있는지 확인하는 과정을 통해 변수의 정보를 읽는다.
//1. 변수에 원시자료형 데이터를 넘기면
let a = 2;
let b = a; // b에 a를 복붙함. 원본은 따로있다.
b = 1; // >>> a는 2, b는 3.
//2. 변수에 참조자료형 데이터를 넘기면
let person = {name: '홍길동'};
let customer = person; //person의 heap 주소를 넘긴다.
customer.name = '둘리'; // >>> person의 name 값은 둘리로 바뀐다.
//3.
let person = {name: '홍길동'};
let customer = person; //person의 heap 주소를 넘긴다.
customer = '둘리'; // >>> person과는 상관없는 별개의 값을 가지게 됨
//4.
let score = 70;
function pass(value) {
value = 62;
}
pass(score); //함수를 실행해도 여천히 score은 70
스코프
변수에 접근할 수 있는 범위
1. 블록 바깥에서 선언된 변수는 블록 안에서 사용 가능.
블록 안쪽에서 선언된 변수는 안에서만 사용 가능.
2. 스코프는 중첩
이 가능함.
3. 전역변수(global scope)
가장 바깥에 선언된 변수
반대는 지역변수(local scope)
.
4. 지역변수
는 전역변수보다 우선순위가 높다!
중괄호로 둘러싼 범위
화살표 함수
var 사용을 지양하는 이유
: block scope를 무시한다.(화살표 함수의 scope는 따름)
block을 벗어나도 바깥에서 접근이 가능하다.
함수로 둘러싼 범위
let 은 재선언을 방지한다.
let은 scope를 지킨다.
값이 변하지 않는 상수.
값을 새로 할당할 일이 없다면 const를 사용한다.
전역 변수에 너무 많은 변수를 선언하지 말아야함.
let, const 사용
선언 없이 변수를 할당하면 전역변수처럼 취급됨.
'strict mode' : 브라우저가 엄격하게 작동하도록 함.
'use strict'; function err(){ errCode = 500; console.log(errCode); //90 } err(); //>>> errCode = 500에 레퍼런스에러 뜸
함수를 리턴하는 함수
리턴하는 함수에 의해 스코프가 구분됨(스코프를 이용해 변수의 접근 범위를 폐쇄함)
데이터를 보존하는 함수. 외부함수 실행이 끝나도 인자로 받은 값을 담고있음!
내부함수를 여러개 만들 수도 있다.
클로저는 함수와 함수가 선언된
어휘적 환경
의 조합이다.
변수 및 함수 선언의 형태
위 정의에서 말하는 “함수”란 반환된 내부함수를 의미하고 “그 함수가 선언될 때의 렉시컬 환경(Lexical environment)”란 내부 함수가 선언됐을 때의 스코프를 의미한다. 즉, 클로저는 반환된 내부함수가 자신이 선언됐을 때의 환경(Lexical environment)인 스코프를 기억하여 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수를 말한다. 이를 조금 더 간단히 말하면 클로저는 자신이 생성될 때의 환경(Lexical environment)을 기억하는 함수다라고 말할 수 있겠다.
https://poiemaweb.com/js-closure
캡슐화, 모듈화에 유리하다.
//동일한 동작을 하는 코드임
//1.
const sum = a => b => a + b;
sum(1)(2)//3
//2.
const sum = function (a) { //외부함수 a는 b에 접근불가
return function (b) { //내부함수 b는 a에 접근 가능
return a + b;
}
}
//특정 데이터를 스코프 안에 가두어 둔 채로 계속 사용함
const tagMaker = tag => content => `<${tag}>${content}</${tag}>`;
const divMaker = tagMaker('div');
divMaker('hello') //'<div>hello</div>'
const buttonMaker = tagMaker('button');
buttonMaker('click'); //'<button>click</button>'