D+13 / [JavaScript] 핵심 개념과 주요 문법 - 원시 & 참조 자료형, 스코프

김서연·2022년 7월 11일
0

프론트엔드

목록 보기
7/12

* 원시 자료형(primitive data type)

: number, string, boolean, nullm undefined와 같은 고정된 저장 공간을 차지하는 데이터를 말한다. ( 객체가 아니면서 method를 가지지 않는 타입을 말한다)

  • 원시타입 데이터는 각 변수간의 원시타입 데이터를 복사할 경우, 데이터값이 복사되기 떄문에 만약 복사된 데이터가 바뀌더라도 기존의 데이터에 영향이 가지 않는다

    ex) let a = 1;
        a = b; // b=1 ->데이터 복사
        b = 2; // 데이터값 바뀜
        a; // 2 기존 데이터에 영향이 가지 않음
  • 왜 원시 자료형이라고 부르는가?
    원시 자료형은 모두 '하나'의 정보, 즉 데이터를 담고 있다. 옛날에는 데이터 저장소(메모리)의 용량이 제한되어 변수 하나에 데이터 용량이 제한된 하나의 원시 자료형 밖에 담을 수밖에 없었기 때문이다.

  • 변수에는 하나의 데이터만 담는다. 값 자체에 대한 변경이 불가능(immutable)하다.

    let word = "hello world!"
     word = "hello codestates!" // 하지만, 변수에 재할당을 하여 변수에 담긴 내용을 변경하는 것은 가능하다. 하지만 const(상수)는 재할당은 불가능하다.

* 참조 자료형(reference data type)

: 대량의 데이터를 다루기에 적합한 배열, 객체, 함수가 대표적이다.

  • 참조 자료형 변수에는 특별한 데이터 보관함(heap)을 찾아갈 수 있는 주소(참조값-refer)가 담겨있고, 이 주소를 따라가 보면 heap을 찾을 수있는데, heap은 자기 마음데로 사이즈를 눌렸다가 줄였다가 할 수 있다.('동적으로 변한다'라고도 한다.)
    이처럼 데이터는 별도로 관리되고, 우리가 직접 다루는 변수에는 주소가 저장되기 떄문에 참조 자료형 이라고 부른다.
    흔히 참고 자료를 찾을 때, 레퍼런스(reference)를 찾는다고 종종 이야히한다. 이 레퍼런스란 단어는 본래 참조할 만한 자료라는 영어 단어로 실생활에서 자주 쓰이지만, 컴퓨터 공학에서는 변수가 가리키고(refer)있는 데이터를 참조한다는 의미로 사용된다.
    그 변수의 주소를 "참조"하여 실제 변수가 있는 장소에 어떤 데이터가 있는지 도착하고 나서야 비로소 "읽을 수" 있다.
  • 참조타입 데이터를 복하사는 경우, 주소를 복사하게된다. 복사한 데이터에서 원소를 변경하게 되면 주소안에 있는 데이터가 변경이 되는것으로, 기존의 데이터에도 영향이 간다.
    ex) let e = [10, 20];
        let f = e; // f = [10, 20] -> 데이터 복사 
        f[0] = 50; // f = [50, 20] ->데이터 변경
        e; // [50, 20] -> 기존 데이터에 영향이 간다.
  • 퀴즈
    • 코드가 실행된 후, 콘솔에 찍히는 값은 각각 무엇인가?
      console.log(3.14 === 3.14);
      console.log([1,2,3] === [1,2,3]); // false -> 참조 자료형은 heap이라는 별도의 메모리 저장공간을 사용한다. 컴퓨터는 두개의 heap공간의 주소를 확보하기 떄문에 주소값을 달라서 false이다.
    • 코드가 실행된 후, x.foo의 값은 무엇인가?
      let x = { foo: 3 };
      let y = x;
      y = 2 // x.foo = 3 -> y는 x의 주소값을 할당받았으나, 2를 재할당 받아 x의 참조자료형 {foo : 3}에는 아무런 영행을 미치지 않는다.
    • 코드가 실행된 후, score 의 값은 무엇인가?
      let score = 80;
      function doStuff(value) {
      value = 90;
      }
      doStuff(score) // 80 -> 매개변수 value에 score의 값 80이 전달되고, value에는 90이 할당된다.
      다만 score의 값 80은, 참조 자료형이 아니기 때문에 주소값을 전달하지 않고, 값 자체를 복사하여 전달하게된다.
      그래서 함수에서 어떤 일이 발생했던가와 관련이 없이 score는 초기에 할당된 값 80이 그대로 유지된다.

* 스코프(Scope)

: 영어 단어의 뜻은 '범위'를 의미한다. JavaScript에서의 스코프는 '변수의 유효범위'로 사용된다.

  • 안쪽 스코프에서 바깥쪽 스코프로는 접근할 수 있지만 반대는 불가능!

  • 스코프는 중첩이 가능하다. 가장 바깥쪽의 스코프는 전역 스코프(Global Scope)라고 부르고, 전역이 아닌 다른스코프는 전부 지역 스코프(local scope)이다.
    (( 전역 스코프에서 선언한 변수는 전역변수, 지역 스코프에서 선언한 변수는 지역변수이다.))

  • 지역 변수는 전역 변수보다 더 놓은 우선순위를 가진다.

  • 문제 : 콘솔에 출력되는 결과는?

     1. let name = '김코딩';
       function showName() {
         let name = '박해커'; // 지역 변수 -> 원래 재선언은 할수 없다고 알고 있었는데, 개별적인 블럭 스코프 안에서는 이름 충돌이 발생하지 않는다.
         console.log(name); 
       }
       console.log(name); //  김코딩
       showName();        //  박해커 -> 지역 변수가 전역 변수보다 우선순위가 높으므로, 지역 변수 name이 출력된다. 동일한 변수 이름으로 인해 바깥쪽 변수가 안쪽 변수에 의해 가려지는(shadow) 이러한 현상을 쉐도잉(variable shadowing)이라고 부른다.
       console.log(name); //  김코딩
      2. let name = '김코딩';
       function showName() { 
         name = '박해커';    // 위의 1번 문제와 다르게, let 키워드를 사용한 선언이 존재하지 않는다. 이는, '박해커'라는 값으로 할당하고 있는 name 변수는 전역에 선언된 name 변수를 그대로 사용하겠다는 의미이다.( 지역 스코프에서 새로 선언되지 않으면 그냥 같은 변수이다.)
         console.log(name); 
       }
    
       console.log(name); // 김코딩
       showName();        // 박해커
       console.log(name); // 박해커 -> showName 함수가 실행되기 전, 처음에는 '김코딩'을 출력하고, 그 이후에는 전역변수 name의 값이 바뀌기 때문에 두 번째 및 세 번째 출력에 '박해커'가 출력된다.
  • 스코프 종류와 키워드
    • 종류
      1. 블록 스코프(block scope) : {}중괄호를 기준으로 범위가 구분된다.
      2. 함수 스코프(function scope) : funciton (){} , 함수의 실행부터 종료까지이다.
      • 유의점 : 화살효 함수(2일차에 내용있음)는 블록 스코프로 취급된다!! 함수이름 제외하고 파라미터부터 {}중괄호까지가 블록스코프
    • let, const, var 키워드
       1. for (let i = 0; i < 5; i++)
            console.log(i); 
          }
          console.log('final i:', i); // ReferenceError ->블록 스코프 안에서 정의된 변수 i는 블록 범위를 벗어나는 즉시 접근할 수 없다.
        2. 위와 달리 let대신 var 키워드를 사용
          for (var i = 0; i < 5; i++)
            console.log(i); 
          }
          console.log('final i:', i); // 5 -> 어떻게 블록을 벗어났는데도 변수 i에 접근할수 있었을까?
           **  var 키워드는 for문이 만들어낸 블록 스코프를 무시하고, 같은 함수 스코프만 따른다. 그러나!! 화살표 함수의 블록 스코프는 무시하지 않는다.
      • var
        = 유효범위 : 함수 스코프 -> var 키워드는 화살표 함수의 블록 스코프를 제외한 나머지 블록스코프를 무시한다. 블록 단위로 스코프를 구분했을때 훨씬 더 예측 가능한 코드를 작성할수 있다-let, const
        = 재할당 가능
        = 재선언 가능
      • let
        = 유효범위 : 블록 스코프, 함수 스코프
        = 재할당 가능
        = 재선언 불가능
      • const : 변하지 않는 값, 상수(constant).
        = 유효범위 : 블록 스코프, 함수 스코프
        = 재할당 불가능 -> 값을 재할당할 경우 TypeError를 내므로, 의도하지 않은 값의 변경을 막을 수 있다.
        = 재선언 불가능
    • 변수 선언에서 주의할 점
      1. var로 선언된 전역 변수 및 지역 함수는 window 객체에 속하게 된다.
      • 브라우저에는 브라우저 창을 대표하는 window라는 객제가 존재한다.
      • 그러나, 브라우저 창과 관계없이 전역 항목도 담고 있다.
        var myName = '김코딩';
         console.log(window.myName);  // 김코딩
         funciton foo() {
           console.log('bar');
         }
         console.log(foo === window.foo);  // true
      1. 전역변수에 너무 많은 변수를 선언하면 안된다.
      • 전역변수는 가장 바깥 스코프에 정의한 변수이다. 따라서 어디서든 접근이 가능하다.
        보통 어플을 만들떄 내가 직접 작성하지 않은 다른 함수와 로직이 포함되는데, 똑같은 이름으로 전역변수를 선언할 수도 있어, 문제가 발생한다 ( 스코프 안에 있으면 다른 스코프의 변수와는 이름충돌 없음)
      1. let, const를 주로 사용
      • var는 블록 스코프를 무시하며, 재선언을 해도 에러를 내지 않는다. 같은 스코프에서 동일한 이름의 변수를 재선언 하는것은 버그를 유발하기 떄문이다. -let, const는 재선언을 방지한다.
      • 전역 변수를 var로 선언하면 window 기능을 덮어씌워서 내장 기능을 사용할 수 없게 만들 수 있다.
      1. 선언 키워드 (let, const, var)없이 변수 할당하면 안된다.
      • 선언 없이 변수를 할당하면, 해당 변수는 var로 선언한 전역 변수처럼 취급된다.
      • js 파일 상단에 'use strict'라고 입력하면 Strict Mode가 적용된다. Strict Mode는 브라우저가 엄격하게 작동되도록 만들어주어 '선언 없는 변수 할당'의 경우에 에러로 판단한다.
profile
프론트엔드 엔지니어로 성장

0개의 댓글