4 분 소요

호이스팅 (Hoisting) : 선언문을 코드 맨 위에 올려진 것처럼 동작시키는 것

평가 (evaluation) : 표현식을 해석해서 값을 생성하거나 참조하는 것

  • 평가 = 인터프리터로서의 컴파일 (선언문 실행 + 호이스팅)
  • 인터프리터로서의 실행 순서 : 전역 코드 평가 → 전역 코드 실행 → 함수 코드 평가 → 함수 코드 실행 → 복귀
  • 변수, 함수, 클래스와 같이 키워드를 사용해서 선언하는 모든 식별자는 호이스팅이 이루어짐
  • 스코프 별로 평가가 이루어지면서 호이스팅이 일어남 → 해당 스코프의 상단으로 올려 메모리 선점 (Linking)
    • let, const도 호이스팅되지만, 초기화되기 전에 접근하면 안됨 (notInitializedYey 상태로 호이스팅)
    • 선언문이 없는 변수는 호이스팅되지 않으며, 평가한 다음에 코드를 실행할 때 정의
console.log(a);
var a = 10;
> undefined

let v;
console.log(v); // 에러

z = 9; // 암묵적으로 var로 정의
console.log(z);
> 9

console.log(globalThis['z']);

let z = 11; // 에러 (암묵적 정의 → 호이스팅)
  • 코드 평가 시점에 호이스팅이 일어나 선언부와 구현부로 구분 → 선언부는 스택 영역에, 구현부는 힙 영역에 저장

  • 선언문의 실행 시점 : 선언문은 런타임 (Runtime)이 아닌 그 이전인 평가 과정에 실행
    • 소스 코드를 한 줄씩 순차적으로 실행하기 앞서, 먼저 소스 코드의 평가 과정에서 선언문을 먼저 실행
    • 즉, 식별자를 선언하는 선언문과 값을 할당하는 할당문의 실행 시점은 서로 다름

동적 타이핑 (Dynamic Typing) : 변수를 선언할 때 데이터 타입을 사전에 선언하지 않음

정적 타입 (Static Typing) : 변수를 선언할 때 데이터 타입을 사전에 선언

  • 변수에 선언한 타입에 해당하는 값만 할당할 수 있음
  • 컴파일 시점에 타입 체크 (Type Check)를 수행하고, 통과하지 못하면 에러를 발생시킴
  • 타입의 일관성을 강제해 안정ㅇ적인 코드의 구현을 통해 런타임에 발생하는 에러를 줄임
  • 자바스크립트는 var, let, const 키워드를 통해 변수만 선언할 수 있음
    • 자바스크립트의 변수는 선언이 아닌 할당에 의해 타입이 결정되는 타입 추론 (Type Inference)이 이루어짐
    • 재할당에 의해 변수의 타입은 언제든지 동적으로 변화할 수 있음 (loosely data)
  • 동적 타이핑 및 동적 타입 언어의 단점 : 유연성 (Flexibility)은 높지만 신뢰성 (Reliability) 이 떨어진다.
    • 동적 타입 언어의 변수 값은 언제든지 변할 수 있음
      • 복잡한 프로그램에서는 변수 값을 추적하기 어려울 수 있음
    • 동적 타입 언어의 변수는 값의 변경에 의해 타입 또한 언제든지 변경될 수 있음
      • 값을 확인하기 전에는 타입을 확신할 수 없음
      • 자바스크립트 엔진에 의해 타입이 자동으로 변환될 수도 있음

자비스크립트에서 변수를 사용할 때 지켜면 좋은 규칙!

  • 변수는 꼭 필요한 경우에 한해 제한적으로 사용한다.
  • 변수의 유효 범위인 스코프는 최대한 좁게 만들어 변수의 부작용을 억제한다.
  • 전역 변수는 최대한 자제한다.
  • 변수보다는 상수를 사용해 값의 변경을 억제한다.
  • 변수 이름은 목적 및 의미를 파악할 수 있도록 네이밍하고, 특히 스코프가 넓을수록 명확하게 명명한다.

타입 변환 (Type Conversion) : 값의 타입이 다른 자료형으로 변환되는 것

  • typeof() 연산자를 통해 피연산자의 데이터 타입을 문자열로 반환할 수 있음

암묵적 타입 변환 : 자바스크립트 엔진에서 에러를 발생시키지 않도록 타입을 바꿔 표현식을 평가하는 것

  • 문자열 타입 변환 : +의 피연산자 중 하나가 문자열이면, 문자열 연결 연산자로 동작하므로 다른 것을 문자열로 변환
  • 숫자 타입 변환 : 산술 및 비교 연산자의 피연산자 중에 숫자 타입이 아닌 피연산자를 숫자 타입으로 변환
  • 불리언 타입 변환 : 논리적 참/거짓을 평가하는 경우에 불리언 타입이 아닌 피연산자를 불리언 타입으로 변환

명시적 타입 변환 : 의도적으로 값의 타입을 변환하는 것 → 타입 캐스팅 (type casting)

  • 문자열 타입으로 변환 : String(), toString(), 문자열 연결 연산자 +
  • 숫자 타입으로 변환 : Number(), parseInt()/parseFloat(), +, *
  • 불리언 타입으로 변환 : Boolean(), 부정 논리 연산자 !를 2번

기존 원시 타입을 사용해 다른 타입의 새로운 원시 타입을 생성하는 것!

  • 원시 타입은 변경 불가능한 값 (immutable value) → 기존 원시 타입을 직접 변경할 수 없음
  • 자바스크립트 엔진에서 표현식을 평가하기 위해 피연산자의 값을 암묵적 타입 변환으로 새로운 타입의 값을 만듬

단축 평가 (Short-Circuit Evaluation) : 표현식을 평가하는 중에 결과가 확정되면, 평가 생략

  • 논리 평가 : 논리 연산자를 이용한 단축 평가 (좌항에서 우항으로 평가)
    • 논리곱 연산자 &&는 두 피연산자가 모두 true일 때, true 반환
      • 논리 연산의 결과를 결정하는 두번째 피연산자를 그대로 반환
    • 논리합 연산자 ||는 두 피연산자 중 하나만 true이여도, true 반환
      • 논리 연산의 결과를 결정하는 첫번째 피연사자를 그대로 반환
'Cat' && 'Dog' // true && 'Dog' → 'Dog'
'Cat' || 'Dog' // 'Cat'... → 'Cat'

논리 평가를 사용하는 경우?

  • 객체를 가리키기 기대하는 변수가 null 혹은 undefined가 아닌지 확인하고 프로퍼티를 참조할 때
var elem = null;
// var value = elem.value; // TypeError
var value = elem && elem.value; // null
  • 함수 매개변수에 undefined가 할당되지 않도록 기본값을 설정할 때
function getStringLength() {
str = str || '';
return str.length;
}
getStringLength(); // 0
getStringLength('hello'); // 5
  • 옵셔널 체이닝 (Optional Chaining) 연산자 ? : 좌항의 피연산자가 null 혹은 undefined이면 undefined를 반환하고, 그렇지 않으면 우항의 프로퍼티 참조를 그대로 진행함
var elem = null;
var str = '';

var value1 = elem?.value; console.log(value1); // undefined
var value2 = elem && elem.value; console.log(value2); // null
var value3 = str && str.length; console.log(value3); // ''
var value4 = str?.length; console.log(value4); // 0
  • null 병합 연산자 ?? : 좌항의 피연산자가 null 혹은 undefined이면 우항의 피연산자를 반환하고, 그렇지 않으면 좌항의 피연산자를 반환 → 변수에 기본값을 설정할 때 사용
    • 논리 연산자 ||를 사용한 단축 평가와 달리, 피연산자가 false로 평가받는 Falsy 값이라도 null 혹은 undefined이 아니면, 좌항의 피연산자를 반환함
var foo = null ?? 'default'; // 'default'
  • Falsy 값 : 피연산자가 false로 평가받는 값 (false, undefined, null, 0, -0, NaN, '')
  • Truthy 값 : 피연산자가 True로 평가받는 값 (true, …)

태그:

업데이트: