[JavaScript] 자바스크립트 - (1)

배창민·2025년 11월 20일
post-thumbnail

자바스크립트 - (1)

변수 · 연산자 · 객체 리터럴 · 함수


1. 변수와 데이터 타입

1-1. 자바스크립트의 7가지 데이터 타입

자바스크립트(ES6 기준)는 7개의 데이터 타입을 제공하며, 크게 원시 타입객체 타입으로 나뉜다

  • 원시 타입(primitive)

    • number
    • string
    • boolean
    • undefined
    • null
    • symbol (ES6)
  • 객체 타입(object)

    • 객체, 배열, 함수 등 원시 타입을 제외한 모든 값

1) number (숫자 타입)

var integer = 10;
var double = 5.5;
var negative = -10;
  • 자바처럼 int, double 등으로 나누지 않고 숫자 타입 하나만 존재

  • 모든 숫자는 실수로 처리

  • 특수한 값

    • Infinity (양의 무한대)
    • -Infinity (음의 무한대)
    • NaN (산술 연산 불가, Not-a-Number)

2) string (문자열 타입)

var str1 = 'JavaScript';
var str2 = "JavaScript";
var str3 = `JavaScript`; // 백틱 (템플릿 리터럴)
  • 작은따옴표, 큰따옴표, 백틱 모두 사용 가능
  • 문자열은 원시 타입이고 불변(immutable)

템플릿 리터럴(Template Literal)

const name = '홍길동';
const msg = `안녕하세요, ${name}님!`;
  • 여러 줄 문자열
  • ${ } 안에 표현식 삽입 가능
  • 백틱을 사용

3) boolean (논리 타입)

var flag = true;
flag = false;
  • true / false 두 값만 존재

4) undefined / null

var undef;
console.log(undef); // undefined

var val = 'something';
val = null; // 의도적으로 '값 없음'을 명시
  • undefined

    • 변수를 선언만 하고 값을 할당하지 않았을 때 자동으로 들어가는 값
    • JS 엔진이 초기화용으로 쓰는 값이므로 개발자가 일부러 대입하는 것은 지양
  • null

    • “현재 이 변수는 아무 것도 참조하지 않는다”는 것을 의도적으로 명시할 때 사용
    • 더 이상 사용하지 않는 객체 참조를 끊을 때 사용 → GC 대상

5) symbol / object

var key = Symbol('key'); // 유일한 값
var obj = {};
var func = function () {};
var arr = [];
  • symbol

    • ES6에서 도입된 7번째 타입
    • 중복되지 않는 유일한 값 → 객체의 고유한 프로퍼티 키로 사용
  • object

    • 자바스크립트는 “객체 기반 언어
    • 원시 타입 6개를 제외한 모든 값은 객체

1-2. 동적 타입 언어의 특징 (Java와의 차이)

자바스크립트는 동적 타입 언어입니다.

  • 정적 타입 언어(C, Java 등)

    • int num; 처럼 변수 선언 시 타입을 명시
    • 컴파일 시점에 타입 체크 → 타입 안정성 높음
  • 동적 타입 언어(JavaScript, Python)

    • var, let, const로 선언할 때 타입을 쓰지 않음
    • 할당되는 값에 따라 타입이 동적으로 결정
    • 재할당 시 타입도 바뀔 수 있음
let value = 10;      // number
value = 'hello';     // string
value = true;        // boolean

동적 타입 언어 사용 시 주의점

  1. 변수는 꼭 필요할 때만 사용
  2. 스코프를 최대한 좁게 유지
  3. 전역 변수 지양
  4. 가능하면 상수(const) 사용으로 값 변경 최소화
  5. 변수 이름만 보고도 역할이 이해되도록 의미 있는 네이밍

1-3. 암묵적 / 명시적 타입 변환

자바스크립트는 상황에 따라 값을 다른 타입으로 자동 변환하기도 하고, 개발자가 직접 변환하기도 함

1) 암묵적 타입 변환 (implicit coercion)

문자열로 변환

console.log(10 + '20'); // '1020'
  • + 연산자는 피연산자 중 하나라도 문자열이면 문자열 연결을 시도

숫자로 변환

console.log(10 - '5');  // 5
console.log(10 > '5');  // true
console.log(+'');       // 0
  • 산술/비교 연산 시 숫자가 아니면 숫자로 변환 후 연산

불리언으로 변환 (Truthy / Falsy)

if (undefined) console.log('실행 X');
if (null) console.log('실행 X');
if (0) console.log('실행 X');
if (NaN) console.log('실행 X');
if ('') console.log('실행 X');

if ('JavaScript') console.log('실행 O');
  • false로 취급되는 값(Falsy): undefined, null, 0, NaN, ''
  • 나머지는 대부분 true로 평가(Truthy)

2) 명시적 타입 변환 (explicit coercion)

문자열로

String(10);
(10).toString();
10 + '';

숫자로

Number('10');
parseInt('10');
parseFloat('10.01');
+'';        // 0
'10' * 1;   // 10

불리언으로

Boolean('JavaScript'); // true
!!'JavaScript';        // true

2. 연산자 정리 (비교, 논리, ES11 연산자)

2-1. 비교 연산자: == vs ===

console.log(1 == '1');     // true
console.log(1 == true);    // true

console.log(1 === '1');    // false
console.log(1 === true);   // false
  • == (동등 비교)

    • 타입이 다르면 암묵적 타입 변환 후 값 비교
  • === (일치 비교)

    • 타입과 값 모두 같은지 비교
  • 실무에서는 거의 항상 === 사용을 권장


2-2. 논리 연산자와 단축 평가

console.log('apple' || 'banana'); // 'apple'
console.log('apple' && 'banana'); // 'banana'
  • A || B

    • A가 Truthy → A 반환
    • A가 Falsy → B 반환
  • A && B

    • A가 Falsy → A 반환
    • A가 Truthy → B 반환

이렇게 결과가 확정되는 순간 평가를 멈추는 것
단축 평가(short-circuit evaluation)라고 한다.


2-3. ES11 연산자 (옵셔널 체이닝, null 병합)

1) 옵셔널 체이닝 ?.

var obj = null;
var val = obj?.value;
console.log(val); // undefined
  • 좌항이 null 또는 undefined에러 대신 undefined 반환
  • 그렇지 않으면 우항 프로퍼티를 이어서 접근
const user = null;
console.log(user?.profile?.name); // undefined, 에러 발생 X

2) null 병합 연산자 ??

var test = null ?? '기본 값';
console.log(test); // '기본 값'
  • 좌항이 null 또는 undefined일 때만 우항을 반환
  • 기본값 설정에 유용
const input = 0;
const val = input ?? 10;
console.log(val); // 0  (0은 null/undefined가 아니므로 그대로 사용)

3. 객체 리터럴(object literal)

3-1. 객체와 프로퍼티, 메서드 기본 개념

자바스크립트는 객체 기반 언어이고, 원시 값을 제외한 대부분이 객체

var student = {
  // 프로퍼티(속성)
  name: '유관순',
  age: 16,

  // 메서드(함수)
  getInfo: function () {
    return `${this.name}(은)는 ${this.age}세입니다.`;
  }
};
  • 프로퍼티(property): 키(key) : 값(value)
  • 메서드(method): 프로퍼티 값이 함수인 경우

3-2. 프로퍼티 키와 값

var student = {
  name: '유관순', // 키: name, 값: '유관순'
  age: 16
};
  • 프로퍼티 키

    • 문자열 또는 symbol
    • 식별자 규칙을 지키면 따옴표 생략 가능
    • 규칙을 지키지 않는 키는 반드시 따옴표 필요

3-3. 메서드와 프로퍼티 접근

var dog = {
  name: '뽀삐',
  eat: function (food) {
    console.log(`${this.name}(은)는 ${food}를 맛있게 먹어요.`);
  }
};

프로퍼티 접근 방법

console.log(dog.name);     // 마침표 표기법
console.log(dog['name']);  // 대괄호 표기법
  • 대괄호 표기법 사용 시

    • 키는 문자열로 적어야 함
    • 식별자 규칙을 지키지 않는 키는 대괄호만 사용 가능

3-4. 프로퍼티 변경, 추가, 삭제

var dog = { name: '뽀삐' };

dog.name = '두부'; // 값 변경
dog.age = 3;       // 프로퍼티 동적 추가
delete dog.age;    // 삭제
  • 없는 키에 값을 대입 → 동적 추가
  • delete 객체.프로퍼티 → 프로퍼티 삭제 (없는 키는 조용히 무시)

3-5. ES6 객체 리터럴 확장 문법

1) 프로퍼티 값 단축 표기

var id = 'p-0001';
var price = 30000;

var product = { id, price };
// { id: 'p-0001', price: 30000 }
  • 변수 이름과 프로퍼티 키가 같으면 id: idid로 축약 가능

2) 계산된 프로퍼티 이름

var prefix = 'key';
var index = 0;

var obj = {
  [`${prefix}-${index++}`]: index,
  [`${prefix}-${index++}`]: index,
  [`${prefix}-${index++}`]: index
};
  • 객체 리터럴 내부에서 대괄호 안에 표현식을 넣어 키를 동적으로 생성 가능

3) 메서드 축약 표현

var dog = {
  name: '두부',
  eat(food) {
    console.log(`${this.name}(은)는 ${food}를 맛있게 먹어요.`);
  }
};
  • eat: function (food) { ... }eat(food) { ... }로 축약

3-6. in 연산자와 for...in

var student = { name: '유관순' };

console.log('name' in student);   // true
console.log('height' in student); // false
  • in 연산자로 프로퍼티 존재 여부 확인
var student = {
  name: '유관순',
  age: 16
};

for (var key in student) {
  console.log(`${key} : ${student[key]}`);
}
  • for...in 반복문으로 객체의 모든 키 순회 가능

4. 함수(function)

4-1. 함수 정의 방식

1) 함수 선언문 (function declaration)

function hello(name) {
  return `${name}님 안녕하세요!`;
}
  • 함수 이름 필수
  • 호이스팅의 영향을 받음 → 선언 이전에 호출 가능

2) 함수 표현식 (function expression)

var hello = function (name) {
  return `${name}님 안녕하세요!`;
};
  • 이름을 생략한 익명 함수도 사용 가능
  • 변수에 할당되는 시점(런타임)에 함수 객체 생성 → 할당 이후에만 호출 가능

3) 함수 호이스팅

// 함수 참조
console.log(hello);
console.log(hi);

// 함수 호출
console.log(hello('홍길동'));
// console.log(hi('홍길동')); // TypeError: hi is not a function

function hello(name) {
  return `${name}님 안녕하세요!`;
}

var hi = function (name) {
  return `${name} 안녕~`;
};
  • 함수 선언문: 선언 이전에도 참조/호출 가능 (함수 호이스팅)
  • 함수 표현식: 변수 호이스팅만 되고 값은 undefined → 할당 전 호출 시 오류

4-2. 매개변수와 인수, 반환

1) 매개변수 / 인수 특징

  • 함수는 매개변수 개수와 인수 개수를 체크하지 않음
  • 인수가 부족하면 → 해당 매개변수는 undefined
  • 인수가 많으면 → 초과 인수는 무시되지만 arguments 객체에 담김
  • ES6 이후는 매개변수 기본값 사용 가능

2) return

  • return 뒤의 값을 함수 호출 결과로 반환
  • 반환문이 없으면, 또는 값을 생략하면 → undefined 반환

4-3. 화살표 함수 (Arrow Function)

var message;

// 기존 함수
message = function () {
  return 'Hello World!';
};

// 화살표 함수
message = () => {
  return 'Arrow Function!';
};

// 한 줄일 때는 중괄호 + return 생략 가능
message = () => 'Arrow Functions are Simple!';

// 매개변수 있는 경우
message = (val1, val2) => 'Arrow ' + val1 + val2;

// 매개변수 하나면 괄호 생략 가능
message = val => 'Arrow ' + val;
  • function 키워드 대신 => 사용
  • 항상 익명 함수
  • 본문이 한 줄일 때 간결하게 사용하기 좋음

4-4. 다양한 함수 패턴

1) 즉시 실행 함수 (IIFE)

(function () {
  console.log('익명 즉시 실행 함수! 함수 정의와 동시에 호출!');
})();
  • 정의와 동시에 즉시 1번만 실행
  • 외부에 노출하고 싶지 않은 초기화 코드 등에 사용

2) 재귀 함수 (recursive function)

function factorial(n) {
  if (n <= 1) return 1;
  return n * factorial(n - 1);
}
  • 함수가 자기 자신을 호출
  • 반복문 없이 반복 로직을 표현할 수 있지만,
    잘못 쓰면 무한 재귀 → 스택 오버플로 주의

3) 중첩 함수 (nested function)

function outer() {
  var outerVal = '외부 함수';

  function inner() {
    var innerVal = '내부 함수';
    console.log(outerVal, innerVal);
  }

  inner();
}

outer();
  • 함수 안에 정의된 함수
  • 보통 외부 함수를 돕는 헬퍼 함수 역할

4) 콜백 함수와 고차 함수

function increase(value) {
  return value + 1;
}

function decrease(value) {
  return value - 1;
}

function apply(func, value) {
  return func(value); // 고차 함수가 콜백 호출
}

console.log(apply(increase, 5)); // 6
console.log(apply(decrease, 5)); // 4
  • 콜백 함수(callback): 매개변수로 전달되는 함수
  • 고차 함수(high-order function): 함수를 인수로 받거나, 함수를 반환하는 함수
  • 비동기 처리(이벤트, 타이머, Ajax), 배열 고차 함수(map, filter 등)에서 핵심 패턴

5) 순수 함수 / 비순수 함수

var cnt = 0;

// 순수 함수
function increase(n) {
  return ++n; // 외부 상태를 변경하지 않음
}

cnt = increase(cnt);

// 비순수 함수
function decrease() {
  return --cnt; // 외부 상태(cnt)를 직접 변경
}
  • 순수 함수

    • 외부 상태에 의존 X
    • 외부 상태를 변경 X
  • 비순수 함수

    • 외부 상태에 의존하거나 변경
    • 상태 추적이 어려워져 버그 유발 가능

4-5. 일급 객체로서의 함수

함수는 자바스크립트에서 일급 객체(First-class Object)

일급 객체 조건:

  1. 리터럴로 생성 가능 (런타임에 생성)
  2. 변수나 자료구조(배열, 객체)에 저장 가능
  3. 함수의 매개변수로 전달 가능
  4. 함수의 반환값으로 사용 가능
var hello = function () {
  return '안녕하세요!';
};

var obj = { hello };

function repeat(func, count) {
  for (var i = 0; i < count; i++) {
    console.log(func());
  }

  return function () {
    console.log(`${count}번 반복 완료`);
  };
}

var returnFunc = repeat(obj.hello, 5);
returnFunc();
  • 함수를 값처럼 다룰 수 있기 때문에
    함수형 프로그래밍 패턴을 구현할 수 있음

profile
개발자 희망자

0개의 댓글