var, let, const

장윤희·2022년 9월 21일
0

Js

목록 보기
1/2
post-thumbnail

변수?

변수는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름

선언 : 변수를 실행 컨텍스트의 변수 객체에 등록한다. 이 변수 객체는 스코프가 참조하는 대상
초기화 : 변수 객체에 등록된 변수를 위해 메모리 공간을 확보, 암묵적으로 undefined를 할당해 초기화
할당 : undefined로 초기화된 변수에 실제 값을 할당

변수 선언

* es6에서 let, const 추가
변수 선언은 선언 → 초기화단계를 거쳐 수행

var kmj
console.log(kmj) // output: undefined

console.log(kmj) // output: undefined
var kmj

위의 경우 둘다 undefined이 반환되지만 후자의 경우 변수선언이 런타임이 아니라 이전 단계에서 실행된다

변수선언이 어디에 있던 다른 코드보다 먼저 실행되는데 이를 호이스팅이라고 한다

변수 할당

var kmj // 변수 선언
kmj = 'howdy-mj' // 값의 할당

var kmj = 'howdy-mj' // 변수 선언과 할당

변수 선언은 호이스팅 되어 런타임 이전에 실행
값의 할당은 런타임에 실행

함수 호이스팅

참고 : Hoisting

// 1. 함수 선언문
// 함수 이름 생략 불가능
function add(x, y) {
  return x + y
}

// 2. 함수 표현식
// 함수 이름 생략 가능
var add = function(x, y) {
  return x + y
}
// 함수 이름 작성 시,
// var add = function plus(x, y) {
//   return x + y
// }

// 3. Function 생성자 함수
var add = new Function('x', 'y', 'return x+ y')

// 4. 화살표 함수
var add = (x, y) => x + y

함수가 정의되는데는 위와 같이 4가지 방식이 있다

// 함수 참조
console.dir(add) // output: f add(x, y)
console.dir(sub) // output: undefined

// 함수 호출
console.log(add(2, 5)) // output: 7
console.log(sub(2, 5)) // output: Uncaught TypeError: sub is not a function

// 함수 선언문
function add(x, y) {
  return x + y
}

// 함수 표현식
var sub = function(x, y) {
  return x + y
}

함수선언문의 경우 런타임이전에 실행됨으로 호이스팅 시킬 수 있다

함수표현식은 런타임에서 할당되어 객체가 되기때문에 런타임 이전에는 undefined로 초기화 시킨다

스코프

  • 식별자의 유효범위를 뜻하며 선언된 위치에 따라 유효범위가 달라진다
    전역에 선언된 변수는 전역 스코프, 지역에 선언된 변수는 지역스코프를 갖는다
  • 전역변수는 어디서든 참조 가능하지만,
    지역변수는 자신의 지역과 하의 지역에서만 유효하다
  • js에서 모든 코드블록(if, for, while)이 지역 스코프를 만드는데 이를 블록 레벨 스코프라고 한다
  • 하지만 var 로 선언된 변수는 함수코드블록만을 지역스코프로 인정한다 이를 함수 레벨스코프라고 한다

var 사용의 문제점

  • 변수 중복 선언이 가능 (예기치 못한 값을 반환할 수 있다)
  • 함수 레벨 스코프로 인해 함수외부에서 선언한 변수는 모두 전역변수
    (var 생략 시 암묵적 전역 변수 양산)
  • 변수 선언문 이전에 변수를 참조하면 언제나 undefined를 반환
    (변수 호이스팅)

변수 중복 선언 불가

let

변수 중복 선언 불가, 재할당은 가능

let name = 'kmj'
console.log(name) // output: kmj

let name = 'howdy' // output: Uncaught SyntaxError: Identifier 'name' has already been declared

name = 'howdy'
console.log(name) // output: howdy

const

변수 중복 선언 불가, 재할당도 불가
재할당의 경우, 원시 값은 불가능하지만, 객체는 가능 (불변을 의미하지 않는다)
let과 다른 점은 선언과 초기화를 동시에 진행

const name; // output: Uncaught SyntaxError: Missing initializer in const declaration
const name = 'kmj'

// 원시값의 재할당
const name = 'kmj'
name = 'howdy' // output: Uncaught TypeError: Assignment to constant variable.

// 객체의 재할당
const name = {
  eng: 'kmj',
}
name.eng = 'howdy'

console.log(name) // output: { eng: "howdy" }

블록 레벨 스코프

let, const는 블록 레벨 스코프를 따른다

let a = 1

if (true) {
  let a = 5
}

console.log(a) // output: 1

var 을 사용하는 경우 5를 출력하지만, let으로 선언한 경우 전역에 있는 값을 출력

변수 호이스팅

let

선언과 초기화단계가 분리되어 진행
선언이 런타임이전에 실행되지만, 초기화 되기 전에 변수에 접근하면 참조에러가 뜬다

console.log(name) // output: Uncaught ReferenceError: name is not defined

let name = 'kmj'

const

선언과 초기화를 동시에 진행

console.log(name) // output: Uncaught ReferenceError: Cannot access 'name' before initialization

const name = 'kmj'

기본적으로 변수의 스코프는 최대한 좁게 만드는 것을 권장한다
따라서, var 키워드 보다는 let과 const 키워드를 사용하며,
변경하지 않는 값(상수)이라면 let 보다는 const 키워드를 사용하는 것이 안전하다.

참고자료
https://www.howdy-mj.me/javascript/var-let-const/

profile
멋쟁이

0개의 댓글