원시 자료형과 참조 자료형 심화 , scope , 클로저(closure)[TIL 17일차]

JUNGHUN KIM·2021년 7월 1일
0
post-custom-banner

원시 자료형

원시 자료형이 할당될 때에는 변수에 값(value)자체가 담김.

  • 고정된 저장 공간을 차지하는 데이터를 의미함
  • 변수에는 하나의 데이터만 담음.
  • 데이터 저장공간이 고정되는 이유는 데이터 저장소(메모리)의 용량에 제한되어져 있기 때문에 하나의 변수에 하나의 원시 자료형만 담을수 있음.
  • 값 자체에 대한 변경은 불가능하지만 변수에 다른 데이터를 할당은 가능.

String, number, bigint, boolean, undefined, symbol,(null)이 있음.

원시자료형과 함수의 만남

함수의 매개변수에 해당 변수의 값을 인자로 전달하는것이 포인트.
원시자료형의 경우 참조 자료형이 아니기 때문에 주소값이 아닌 값 자체를 복사해서 전달.

Test1

let score = 80;
function doStuff(value) {
  value = 90;
}

doStuff(score)

매개 변수 value에 score값인 80이 전달됨
value =90에서 value에 90이 할당됨
다만 변수 score의 값 80은 참조 자료형이 아니기 떄문에 주소값을 전달하지 않고,
값 자체를 복사하여 전달하게됨 그래서 함수에서 어떤일이 발생했던가와 관련이 없이
score는 초기에 할당된 값 80이 그대로 유지.

Test2

case1을 조금더 이해하기 쉽게 함수안에서 콘솔로그로 찍어봄
score의 값을 매개변수 value에 할당하였으며 그 이후 value에 90을 재할당
score는 80, value는 90이 찍히는것을 볼 수 있음.

let score = 80;
function doStuff(value) {
  value = 90;
return console.log(`value값:${value} score값:${score}`)
}
doStuff(score) //return된 console.log ==> value값:90 score값:80 

Test3

함수안에서 아무것도 하지 않고 value값과 score값을 바로 return함
score의 값을 매개변수 value의 값에 할당하여 score,value모두 값이 80임을 확인.

let score = 80;
function doStuff(value) {
return console.log(`value의 값은:${value} score의 값은:${score}` )
}
doStuff(score) //return된 value의 값은:80 score의 값은:80

참조 자료형

참조 자료형이 할당돌 경우 보관함의 주소(reference)가 담김

  • 변수에 넣을 데이터의 크기가 제한되었기 때문에 만들어짐.
  • 원시 자료형이 보관되는 데이터 보관함이 아닌 특별한 데이터 보관함(heap)에 저장됨.
    변수를 선언하고 값을 주면 특별한 데이터 보관함을 가리키는 주소가 변수에 저장됨.
  • 데이터 보관함에서는 자기 마음대로 사이즈를 늘렸다 줄였다 하는데 이것을 동적(dynamic)으로 변한다 라고 하며 동적으로 변하는 이유는 값이 한개만 들어온 데이터 보관함에 많은 용량을 쓰는것은 효율이 좋지 않기 때문.

참조 자료형과 함수의 만남

함수가 호출(실행)되면 매개변수에 변수의 값이 할당됨, 하지만 변수가 객체, 배열,함수일 경우
변수가 가지고 있는 주소값을 매개변수에 전달함

이 부분을 기억

let player = { score: 3 };
function doStuff(obj) { 
  obj.score = 2;
}
doStuff(player);

함수 doStuff에 변수 plaey를 인지로 전달하여 호출(실행)
함수가 호출되면 매개변수 obj에 변수 player의 값이 할당되는데 지금의 경우
변수의 값이 객체(secore: 3}이므로 변수가 가지고 있는 주소값을 obj에 전달
obj,player는 같은 주소값을 가지고 있으므로 obj.score =2를 할 경우
player.score또한 2가 됨.


scope

영어단어를 해석하면 범위라는 뜻이며 JavaScript에서는 변수의 유효 범위를 이야기함.

반드시 외우고 이해해야 할것

함수의 파라미터(매개변수)는 하나의 선언된 변수와 같다.

변수 접근 규칙에 따른 유효 범위

  • 안쪽 스코프에서 바깥쪽 스코프로는 접근이 가능하지만 반대는 불가능.
  • 스코프는 중첩이 가능함. 중첩된 울타리와 같음.
  • 가장 바깥쪽의 스코프는 특별히 전역 스코프(Global Scope)라고 부름
    전역 스코프의 반대말은 지역 스코프(Local scope)
  • 지역 변수는 전역 변수보다 더 높은 우선 순위를 가짐.
    지역 스코프에 선언한 변수는 지역변수, 전역스코프에 선언한 변수는 전역변수라고 함
    let name = 'Jung' // 전역변수
    function showName() {
     let name = "kim" // 지역변수
    }

*지역 변수가 전역 변수와 동일한 변수명이며, 지역변수의 우선순위가 높음으로 인해 전역변수가 가려지는(shadow)상황을 쉐도잉(variable shadowing)이라고 부름.

scope예제

let name = '김코딩';

function showName() {
  name = '박해커';
  console.log(name); // 두번째 출력
}

console.log(name); // 첫번째 출력
showName();
console.log(name); // 세번째 출력

정답: 첫번째 출력: 김코딩 , 두번째 출력: 박해커 , 세번째 출력: 박해커
세번째 줄에서 let 키워드를 사용한 선언이 존재하지 않습니다.(지역변수에 새로운 변수할당 X)
이는, '박해커'라는 값으로 할당하고 있는 name 변수는 전역에 선언된 name 변수를 그대로 사용하겠다는 의미. 지역 스코프에서 새로 선언되지 않으면 그냥 같은 변수입니다.

따라서 showName 함수가 실행되기 전, 처음에는 '김코딩'을 출력하고, 그 이후에는 전역변수 name의 값이 바뀌기 때문에 두번째 및 세번째 출력에 '박해커'가 출력

스코프의 종류

1. 블록 스코프 (block scope)

  • 중괄호를 기준으로 범위가 구분

2.함수 스코프(function scope)

  • function 키워드가 등장하는 함수 선언식 및 함수 표현식은 함수 스코프를 만듬.

***주의점

화살표 함수는 블록 스코프로 취급됨, 함수 스코프가 아님.**

let,var,const 키워드 비교

let과 var의 차이

  • let
    아래 for문이 블록스코프이기 때문에 블록 스코프를 벗어나는 대로 변수 사용이 불가능
    for(let i =0; i<2 ; i++) {
    
    }
    console.log(`i의 값은 몇이야? ${i}`) // Uncaught ReferenceError: i is not defined
  • var
    아래 블록 스코프를 무시하고 함수 스코프를 따르기 때문에 var로 설정한 i는 남아 있게됨.
    for(var i =0; i<2 ; i++) {
    
    }
    console.log(`i의 값은 몇이야? ${i}`) // i의 값은 몇이야? 2

클로저(Closuer)

클로저 정의

  • "함수와 함수가 선언된 어휘적(lexical) 환경의 조합을 말한다.
  • 이 환경은 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역 변수로 구성된다.
  • "외부함수의 변수(컨텍스트)에 접근할 수 있는 내부함수"를 클로져 함수라고도 부름
  • 외부함수의 실행이 종료된 후에도, 외부 함수 내 변수가 메모리상에 저장되어져 있음.
  • 스코프들이 독립적으로 동작하는것이 아닌, 내부함수가 외부함수와 서로 상호작용을 하는것

클로저 사용 예시

클로저를 통해 커링(currying, 함수 하나가 n개의 인자를 받는 대신 n개의 함수를 만들어 각각 인자를 받게 하는 방법)
클로저 모듈(변수를 외부 함수 스코프 안쪽에 감추어, 변수가 함수 밖에서 노출되는 것을 막는 방법) 등의 패턴을 구현할 수 있습니다.

클로저의 단점

일반 함수였다면 함수 실행 종료 후 가비지 컬렉션대상이 되었을 객체가, 클로저 패턴에서는 메모리 상에 남아 있게되며 외부 함수 스코프가 내부함수에 의해 언제든지 참조될 가능성이 있음. 따라서 클로저를 남발할 경우 퍼포먼스 저하가 발생할 수도 있으며 자바스크립트는 가비지 컬렉션을 통해 메모리 관리를 합니다. 객체가 참조 대상이 아닐 때, 가비지 컬렉션에 의해 자동으로 메모리 할당이 해제됩니다.

클로저 사용의 예시

profile
개발자가 되고 싶은 일문학도
post-custom-banner

0개의 댓글