leexx
처음 배우는 마음으로
leexx
전체 방문자
오늘
어제
  • 분류 전체보기 (68)
    • 막개발글 (12)
    • 자바스크립트 JavaScript (17)
    • 우아한테크코스 (3)
      • 프리코스 (3)
    • 타입스크립트 TypeScript (2)
    • 리액트 React (9)
      • 리액트 React (4)
      • ReactQuery (3)
      • ReduxToolkit (1)
    • 스프링 Spring (2)
      • 전체 글 (2)
    • 코틀린 Kotlin (4)
    • 자바 Java (9)
    • 파이썬 Python (3)
      • Selenium (2)
    • SQL (1)
    • 깃허브 GitHub (1)
    • 알고리즘 Algorithm (5)
    • 일상글 (0)

인기 글

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
leexx

처음 배우는 마음으로

자바스크립트 JavaScript

변수의 타입과 Scope, Hoisting, 함수

2023. 1. 16. 08:00

타입

타입의 종류

  • 기본형 (Primitive type)
    • null
    • undefined
    • boolean
    • number
    • string
  • 복합형 (Non-Primitive type)
    • object
    • array

 

타입을 체크하는 방법

console.log(typeof a);

 

Undefined? Undefined(Undeclared)?

  • 두 변수들의 값을 출력하려고 한다. 이 때 선언이 되었지만 값이 없는 변수 a 와 선언조차 되지 않은 변수 b가 있다.
    • var a; console.log(a); // undefined
    • console.log(b); // ReferenceError: b is not defined
    • b를 출력할 때 에러가 난다. 이해가 가는 내용이다.
  • 이어서 두 변수들의 타입을 출력하려고 한다. 이 때 선언이 되었지만 값이 없는 변수 a 와 선언조차 되지 않은 변수 b가 있다.
    • var a;
      console.log(typeof a); // undefined
      
      console.log(typeof b); // undefined (undeclared)
    • 두개를 모두 출력하면 undefined 라는 값이 출력된다. a 야 정의되지 않은 것이 맞긴 하지만, 선언조차 되지 않은 b 또한 에러가 뜨지 않고 똑같이 undefined 를 출력한다.
    • 이 점을 활용하여 Reference Error의 안전 가드로 사용할 수 있다. 임의의 변수를 사용하려고 할 때, 이 변수가 선언이 아예 되지 않았는지, 또는 값이 없는지를 체크할 수 있다는 점에서 착안하였다.
    • if (typeof a === "undefined") console.log("변수가 올바르게 선언되지 않았습니다"); if (typeof b === "undefined") console.log("변수가 올바르게 선언되지 않았습니다");

 

JavaScript의 변수의 타입

  • (const를 제외하고) 변수를 선언한 이후 재 할당이 가능하다. 즉 변수가 가진 타입이 계속 바뀔 수 있다는 것이다.
  • 따라서 변수에 typeof 연산자를 대어보는 건 "이 변수의 타입은 무엇이니?" 라는 질문과 같지만, 실은 타입이란 개념은 변수에 없으므로 정확히는 "이 변수에 들어있는 값의 타입은 무엇이니?" 라고 묻는 것이다.

var, let, const의 차이

  • var과 let, const의 차이는 무엇일까?
    • scope가 다르다.
      • var : function-scoped
      • let & const : block-scoped
    • 재 선언, 재 할당 여부가 다르다.

 

 

Function scope, Block scope

  • Function scope
    • function scope를 갖는 var v 는 이처럼 함수 안에서만 존재한다.
  • function f() { var v = 5; console.log(v); // 5 } console.log(v); // ReferenceError: v is not defined
  • Block scope
    • block scope를 갖는 let a 는 이처럼 block 안에서만 존재한다.
  • for (let a = 0; a < 5; a++) { console.log(a); // 0 1 2 3 4 } console.log(a); // ReferenceError: a is not defined

 

var, let, const는 어디에 저장이 될까?

전부 heap에 저장되나요 아니면 일반적인 변수, 상수처럼 heap, stack에 저장되나요?

  • 이는 데이터의 type에 따라 결정이 된다.
  • Primitive type (null, undefined, boolean, number, string) 의 경우 stack에, Non-Primitive type (array, object) 의 경우 heap에 저장된다.

 

Hoisting

Hoisting의 예시와 개념

  • 그렇다면, 이건 결과가 어떻게 나올까? 마지막줄의 console.log() 는 출력이 될까?
    • 답은 그렇다. 출력 결과는 아래와 같다.
    j 0
    j 1
    j 2
    j 3
    j 4
    j 5
    j 6
    j 7
    j 8
    j 9
    after loop j is  10
  • for(var j=0; j<10; j++) { console.log('j', j); } console.log('after loop j is ', j);
  • after loop j is 10 이 출력이 될 수 있는 이유는, 컴파일 과정 중에 var j 를 맨 윗부분에서 선언해주기 때문이다. 즉 위의 코드는 아래와 같은 내용인 것이다
    • var 가 function scope 를 갖는다면서 왜 for문 안이 아니라 전역에 선언이 된 것일까? 왜냐하면 for문은 함수가 아니기 때문이다.
    var j;
    
    for (j = 0; j < 10; j++) {
      console.log("j", j);
    }
    console.log("after loop j is ", j);
  • 이처럼 컴파일 과정 중에 선언문을 맨 위로 끌어올려주어, 해당 scope 내에서 선언과 사용의 순서에 상관 없이 사용할 수 있도록 하는 것을 Hoisting 이라 한다. 함수가 변수보다 우선시된다.
  • 1번과 2번 코드는 3번과 같다. 4번의 경우 ReferenceError 가 뜨지 않고 undefined 가 뜨는 이유는, 생각해보건대 var foo; 는 맨 위로 끌어올려졌지만 값 할당이 console.log() 이후에 일어났기 때문에 var foo가 선언만 되고 값이 할당이 되지 않아서 undefined가 나온 것 같다.
  • // 1. foo = "bar"; var foo; console.log(foo); // bar // 2. foo = "bar"; console.log(foo); // bar var foo; // 3. var foo; foo = "bar"; console.log(foo); // bar // 4. console.log(foo); // undefined foo = "bar"; var foo;

 

Hoisting이 일어나는 경우와 그렇지 않은 경우

  • var 변수/함수의 선언만 위로 끌어올려진다.
  • const, let 같이 선언과 동시에 할당이 되는 경우 에는 끌어올려지지 않는다.
  Hoisting 여부
var O
let X
const X
  • 사실 Hoisting이 일어나지 않는 것은 아니다. 내부적으로는 모두 Hoisting이 일어나지만 TDZ로 인해 (실행 결과만 봤을 때에는 -let, const, 함수 선언식은- ReferenceError가 뜬다) hoisting이 일어나지 않는 것 처럼 보인다.
  • // 출력을 선언보다 먼저했다 // let & const console.log(a); // ReferenceError: a is not defined console.log(b); // ReferenceError: b is not defined let a = "a"; const b = "b"; // 함수 선언식 console.log(ff("15")); // ReferenceError: ff is not defined const ff = function(v) { // 함수 표현식 return v; };

 

var보다 let, const 사용을 지향하는 이유는 Hoisting과 관련이 있다고 생각한다

  • let과 const가 등장한 이래로 var보다는 let, const 사용을 지향해오고 있다. 그 이유는, 생각해보건대 hoisting 때문인 것 같다. var는 (for문의 예시 처럼) 종종 예측하기 어려운 상황을 만들 수 있다.

 

함수

함수 선언문

  • 구성 요소
    • 함수 이름
    • 매개변수
    • 함수 몸체
    • (optional: 반환 값)
function square(number) {
    return number*number;
}

 

함수 표현식

  • 함수의 선언과 동시에 변수에 할당한다.
  • var square = function(number) { return number*number; };
  • 함수가 선언될 때, 함수에 이름이 있냐 없냐에 따라 기명/익명 함수로 나뉜다.
    • 기명 함수
    • var foo = function multiply(a, b) { return a*b; };
    • 익명 함수
    • var bar = function(a, b) { return a * b; };
  • 함수 표현식이 뭔지는 알겠는데, 굳이 왜 하는걸까? 변수 안에 함수를 넣어야 하는 이유는 무엇일까?
    • 유성이가 또 좋은 질문을 해주었다. 그동안 그저 변수에 함수를 넣기만 했지, 왜 그렇게 썼는지 고민을 해 본 적이 없었다.
    • 이유는 함수를 변수처럼 사용하기 위해서 이다. 이를테면,
    1. 다른 함수의 인자로써 사용하거나
    2. 리턴 값으로 사용하거나
    3. 변수나 객체에 할당하거나
    4. 동적으로 객체의 프로퍼티를 생성 또는 할당하거나
    • 를 하기 위해서 이다.

 

참고 자료

  • JavaScript의 변수의 타입 / 책 - You don’t know JS 30page
  • var, let, const / 책 - You don’t know JS 234page
  • Undefined? Undefined? / 책 - You don’t know JS 34page
  • var, let, const는 어디에 저장이 될까? [StackOverflow] Primitive value vs Reference value
  • JavaScript는 Compile 언어일까 Interpreter 언어일까?
    • [HashCode] 자바스크립트는 컴파일언어인가요 인터프리터 언어인가요?
    • 저스트-인-타임(JIT) 컴파일러
  • Hoisting
    • https://asfirstalways.tistory.com/197
    • https://gmlwjd9405.github.io/2019/04/22/javascript-hoisting.html
  • 조건문 https://www.opentutorials.org/module/570/4962
  • 함수 https://poiemaweb.com/js-function
반응형

'자바스크립트 JavaScript' 카테고리의 다른 글

Closure  (0) 2023.01.18
Scope  (0) 2023.01.18
실행 컨텍스트 (Execution Context)  (2) 2023.01.17
JITC, Adaptive-JITC  (0) 2023.01.17
JavaScript 의 역사  (0) 2023.01.16
    '자바스크립트 JavaScript' 카테고리의 다른 글
    • Scope
    • 실행 컨텍스트 (Execution Context)
    • JITC, Adaptive-JITC
    • JavaScript 의 역사
    leexx
    leexx

    티스토리툴바