2025.04.02
인터프리터형 프로그래밍 언어

let name = "Alice";
const age = 25;
스코프는 변수가 어디에서 접근 가능한지를 결정
Node.js 환경에서의 스코프는 전역 스코프와 블록 스코프가 존재
{
let blockScoped = "블록 안에서만 접근 가능";
console.log(blockScoped);
}
var globalScoped = "전역에서 접근 가능";
{
console.log(globalScoped); // 출력: 전역에서 접근 가능
}
더 이상 나눌 수 없는 단일 값

let emptyValue = null;
let uninitialized;
console.log(emptyValue); <!-- 출력: null -->
console.log(uninitialized); <!-- 출력: undefined -->
<!-- Infinity: 무한대 -->
console.log(1 / 0); <!-- 출력: Infinity -->
<!-- NaN (Not-a-Number) : 수학적으로 정의되지 않은 연산의 결과 -> 연산을 수행할 수 없다 -->
console.log("text" * 2); <!-- 출력: NaN -->
키-값 쌍(Key-Value Pair)으로 데이터를 저장하는 구조
객체(Object) : 키-값 쌍으로 데이터를 저장 {}
배열(Array) : 순서가 있는 데이터의 집합 []
다차원 배열 : 여러 차원의 데이터를 저장하는 구조, 행과 열로 구성
함수(Function) : 실행 가능한 코드 블록 function()
객체 배열 : 배열과 객체를 조합 [{}]
메모리 관리
let original = { name: "Alice", age: 25 };
let copy = original; <!-- 메모리 주소를 복사 -->
copy.name = "Bob";
console.log(original.name); <!-- 출력: Bob (original도 영향을 받음) -->
<!-- 함수 : function () -->
let greet = function () {
return "Hello!";
};
console.log(greet()); <!-- 출력: Hello! -->
<!-- 객체 배열 -->
<!-- 객체 배열 안에는 같은 자료형이 아니라도 같이 쓸 수 있다 -->
let students = [
{ name: "Alice", age: 20, score: 85 },
{ name: "Bob", age: 22, score: 90 },
{ name: "Charlie", age: 19, score: 78 }
0,
function() {},
[],
NaN
];
변수나 값의 자료형을 확인하는 데 사용
console.log(typeof null); <!-- 출력: "object" (JavaScript의 오래된 버그) -->
console.log(typeof [1, 2, 3]); <!-- 출력: "object" (배열도 객체의 일종) -->
변수에 저장된 값에 따라 자료형이 자동으로 할당
-> 변수 선언이 아닌 할당에 의해 타입이 결정
-> 재할당에 의해 변수의 타입은 언제든지 동적으로 변할 수 있다.
let test;
<!-- test 변수를 선언하였으나 값을 설정하지 않았으므로
빈 값을 의미하는 undefined 타입이 됨 -->
test = 1;
<!-- 이전 시점에 test 변수는 undefined였으나,
숫자 1이 할당됨으로써 test의 타입은 Number로 변경됨 -->
test = "1";
<!-- "" <- 문자열을 의미하며 "", '' 으로 감싸진 값은 문자열로 취급이 된다. -->
<!-- test 변수에 문자열 "1"가 할당됨으로써, test의 타입은 String으로 변경됨 -->
test = true;
<!-- test 변수에 Boolean 값 true가 할당되면서,
test의 타입은 Boolean으로 변경됨 -->
test = null;
<!-- test 변수에 null이 할당되면서,
test의 타입은 다시 null로 변경됨 -->
test = { name: "Alice" };
<!-- test 변수에 객체가 할당되면서,
test의 타입은 Object로 변경됨 -->
test = [1, 2, 3];
<!-- test 변수에 배열이 할당되면서,
test의 타입은 Array(객체의 한 종류)로 변경됨 -->
console.log(10 + "20");
<!-- 출력: "1020" (숫자가 문자열로 변환되어 연결) -->
console.log("10" * 2);
<!-- 출력: 20 ("10"이 숫자로 변환되어 계산) -->
<!-- 문자열이 숫자로 암묵적으로 변환 -->
<!-- 단항 플러스 연산자 : 주로 변수를 숫자로 변환하는 데 사용 -->
totalScore = +student1Score + +student2Score + +student3Score;
console.log("학생 평균 점수:", totalScore / 3); <!-- 출력: 85 -->
let isStudent1Adult = student1Age - 0 >= 18;
let isStudent2Adult = student2Age - 0 >= 18;
console.log(Boolean(0)); <!-- 출력: false -->
console.log(Boolean("Hello")); <!-- 출력: true -->
console.log(Boolean("")); <!-- 출력: false -->
명확성과 데이터 일관성 유지, 코드의 안정성이 높아진다.
console.log(Number("42")); <!-- 출력: 42 -->
console.log(Number("Hello")); <!-- 출력: NaN -->
console.log(Number(true)); <!-- 출력: 1 -->
console.log(Number(false)); <!-- 출력: 0 -->
console.log(String(42)); <!-- 출력: "42" -->
console.log(String(true)); <!-- 출력: "true" -->
console.log(Boolean(1)); <!-- 출력: true -->
console.log(Boolean(0)); <!-- 출력: false -->
console.log(Boolean("")); <!-- 출력: false -->



==와 ===의 차이
!=와 !==의 차이

조건의 평가를 최소화하여 효율성을 높이는 기법
(조건문) ? 참일 때 값 : 거짓일 때 값
조건이 참(true)일 때 실행되는 코드 블록을 정의
if (조건) {
// 조건이 참일 때 실행할 코드
}
else if (조건) {
// 추가 조건이 참일 때 실행할 코드
}
else {
// 모든 조건이 거짓일 때 실행할 코드
}
주어진 표현식의 값을 평가하여 여러 경우(case) 중 하나에 해당하는 코드 블록을 실행하는 제어 구조
switch (표현식) {
case 값1:
// 값1과 일치할 때 실행할 코드
break;
case 값2:
// 값2와 일치할 때 실행할 코드
break;
default:
// 모든 case와 일치하지 않을 때 실행할 코드
}
반복 횟수가 명확할 때 사용
for (let i = 0; i < 10; i++) {
console.log(i);
}
조건이 참인 동안 반복
let i = 0;
while (i < 10) {
console.log(i);
i++;
}
최소 한 번은 실행한 후 조건을 검사해 반복 여부를 결정
let j = 0;
do {
console.log(j);
j++;
} while (j < 10);
특정 조건에서 반복문을 중단한다.
let searchCart = [1200, 1500, 3000, 4500, 5000];
let searchTotal = 0;
for (let i = 0; i < searchCart.length; i++) {
if (searchCart[i] === 3000) {
console.log("3000원 상품 발견! 계산 중단.");
break; // 반복문 종료
}
searchTotal += searchCart[i];
}
console.log(`계산된 총 가격: ${searchTotal}원`);
특정 조건에서 반복문을 건너뛴다.
let selectiveCart = [1200, 1500, 3000, 4500, 800];
let selectiveTotal = 0;
for (let i = 0; i < selectiveCart.length; i++) {
if (selectiveCart[i] <= 1000) {
continue; // 1000원 이하 상품 건너뜀
}
selectiveTotal += selectiveCart[i];
}
console.log(`1000원 초과 상품 총 가격: ${selectiveTotal}원`);
특정 작업이나 계산을 수행하는 코드 블록으로, 입력값을 받아 처리한 후 결과를 반환하는 구조
function 키워드를 사용하여 선언
function 함수이름(매개변수1, 매개변수2, ...) {
// 함수가 수행할 코드
return 반환값; // 선택 사항
}
function add(a, b) {
return a + b; // 두 매개변수의 합을 반환
}
함수 이름과 괄호를 사용
함수이름(인수1, 인수2, ...);
let result = add(5, 10); // add 함수를 호출하여 5와 10을 전달
매개변수: 함수 선언 시 정의하는 변수
인수: 함수를 호출할 때 전달하는 실제 값
function 함수이름(매개변수1, 매개변수2, ...) {
// 함수가 수행할 코드
return 반환값; // 선택 사항
}
함수이름(인수1, 인수2, ...);
함수의 매개변수에 기본값을 설정할 수 있다.
function multiply(a, b = 1) {
return a * b; // b가 전달되지 않으면 기본값 1 사용
}
console.log(multiply(5)); // 5 출력
console.log(multiply(5, 2)); // 10 출력
함수를 변수에 할당하여 사용할 수 있는 방식
const functionName = function(parameters) {
// 함수 본문
return value;
};
간결한 문법으로 함수를 정의
const functionName = (parameters) => {
// 함수 본문
return value;
};
function f() {};
const f = () => {};
const obj = {
value: 100,
regularFunction: function() {
console.log("일반 함수 this:", this.value); // `obj`를 가리킴
},
arrowFunction: () => {
console.log("화살표 함수 this:", this.value); // 상위 스코프의 `this`를 가리킴
}
};
obj.regularFunction(); // 일반 함수 this: 100
obj.arrowFunction(); // 화살표 함수 this: undefined
name = "전역 이름"; // var name = ... 처럼 전역에 추가됨
const user = {
sayHi2: () => {
console.log(this.name);
},
};
user.sayHi2(); // "전역 이름"
자바스크립트의 함수는 일급 객체이다.
프로그래밍 언어에서 객체가 가지는 특성을 나타내는 용어
const sayHi = function() {
console.log("안녕하세요!");
};
sayHi(); // 출력: 안녕하세요!
function greet(fn) {
fn(); // 전달받은 함수 실행
}
greet(function() {
console.log("반가워요!");
});
function getGreeting() {
return function() {
console.log("좋은 하루!");
};
}
const hello = getGreeting();
hello(); // 출력: 좋은 하루!
변수와 함수가 유효한 범위를 정의
함수 스코프
함수 내부에서 선언된 변수는 함수 외부에서 접근할 수 없다.
function scopeExample() {
var a = "함수 내부";
console.log(a); // 출력: "함수 내부"
}
console.log(a); // 에러: a is not defined
블록 스코프
블록 내부에서 선언된 변수는 블록 외부에서 접근할 수 없다.
{
let b = "블록 내부";
const c = "블록 내부";
console.log(b, c); // 출력: "블록 내부 블록 내부"
}
console.log(b, c); // 에러: b, c is not defined
함수와 함수가 선언될 당시의 렉시컬 환경(Lexical Environment)을 기억하는 기능
function outerFunction(outerVariable) {
return function innerFunction(innerVariable) {
console.log(`Outer: ${outerVariable}, Inner: ${innerVariable}`);
};
}
const closureExample = outerFunction("Outside");
closureExample("Inside"); // 출력: Outer: Outside, Inner: Inside
함수의 인수로 전달되어 특정 작업이 완료된 후 호출되는 함수
다른 함수에 인자로 전달되어 그 함수 내부에서 호출되는 함수
// 콜백 함수 사용 기본 형태
function higherOrderFunction(callback) {
console.log("작업 시작...");
callback(); // 작업 완료 후 콜백 함수 실행
console.log("작업 종료.");
}
// 콜백 함수 정의
function myCallback() {
console.log("콜백 함수 호출됨!");
}
// 실행
higherOrderFunction(myCallback);
<!-- 출력 -->
작업 시작...
콜백 함수 호출됨!
작업 종료.
콜백 함수를 인수로 받거나 다른 함수를 반환하는 함수
키-값 쌍으로 구성된 데이터 구조
객체 리터럴
const person = {
name: '홍길동',
age: 30,
job: '개발자'
};
Object 생성자
const person = new Object();
person.name = '홍길동';
person.age = 30;
person.job = '개발자';
점 표기법
console.log(person.name); // 홍길동
대괄호 표기법
console.log(person['age']); // 30
속성 삭제
데이터뿐만 아니라 함수를 포함
const calculator = {
add: function(a, b) {
return a + b;
}
};
console.log(calculator.add(5, 3)); // 8
순서가 있는 데이터의 집합
배열 리터럴
const fruits = ['사과', '바나나', '체리'];
Array 생성자
const fruits = new Array('사과', '바나나', '체리');
fruits.forEach(fruit => {
console.log(fruit);
});
const lengths = fruits.map(fruit => fruit.length);
데이터를 키-값 쌍으로 저장하는 경량 데이터 교환 형식
자바스크립트 객체
- 자바스크립트의 데이터 구조
JSON
- 텍스트 기반의 데이터 형식
{
"name": "홍길동",
"age": 30
}객체 -> JSON 변환
- 직렬화
- JSON.stringify() 메서드를 사용
JSON.stringify(객체, replacer, space);
- 객체 : 문자열로 반환할 대상
- replacer : 어떤 속성을 포함할지 필터링 (보통 null이면 모든 속성 포함)
- space : 들여쓰기(공백 또는 탭의 수)를 지정 → 가독성을 위한 옵션
JSON -> 객체 변환
- 역직렬화
- JSON.parse() 메서드를 사용
프로그램의 일부 작업을 기다리지 않고 다음 작업을 수행할 수 있도록 설계하는 방식
메인 스레드에서 실행되는 코드가 완료되면, 이벤트 루프가 이벤트 큐에서 대기 중인 콜백 함수를 처리

Node.js는 libuv라는 라이브러리를 통해 블로킹 I/O 작업을 처리하기 위해 백그라운드에서 여러 스레드를 사용하는 스레드 풀을 운영
// setTimeout을 사용한 비동기 실행
setTimeout(() => {
console.log("2초 후 실행되었습니다.");
}, 2000);
// addEventListener를 사용한 이벤트 기반 비동기 실행
document.getElementById("myButton").addEventListener("click", () => {
console.log("버튼이 클릭되었습니다!");
});
const promise = new Promise((resolve, reject) => {
// 비동기 작업
if (/* 성공 조건 */) {
resolve("작업 성공");
} else {
reject("작업 실패");
}
});
promise
.then((result) => console.log(result)) // 성공 시 실행
.catch((error) => console.error(error)); // 실패 시 실행
async function asyncFunction() {
const result = await someAsyncTask();
console.log(result);
}
async function fetchData() {
return new Promise((resolve) => {
setTimeout(() => {
const data = { id: 1, name: '홍길동' };
resolve(data);
}, 1000);
});
}
async function getData() {
const result = await fetchData();
console.log('데이터:', result);
}
getData();
<!-- fetchData()는 async 함수이므로 반드시 Promise를 반환
내부에서 resolve(data)를 호출하면, 이 Promise는 fulfilled 상태가 되고 data를 전달
await fetchData(); → fetchData()가 끝날 때까지 기다렸다가 그 결과(data)를 result에 담음
console.log(...)는 fetchData()가 완료된 후에 실행 -->
비동기 작업을 처리하기 위한 메커니즘
setTimeout: 지정된 시간(ms) 후에 한 번 실행되는 함수
setTimeout(() => {
console.log("1초 후에 실행");
}, 1000)
const reminder = setTimeout(() => {
console.log("이 메시지는 출력되지 않습니다.");
}, 5000);
setTimeout(() => {
clearTimeout(reminder);
console.log("알림이 취소되었습니다.");
}, 2000);
setInterval: 지정된 시간(ms) 간격으로 반복 실행되는 함수
let count = 0;
const intervalId = setInterval(() => {
console.log(`Interval 실행: ${++count}`);
if (count === 5) clearInterval(intervalId); // 5회 실행 후 종료
}, 1000);
다중 행 문자열과 문자열 보간 기능을 지원
const name = "홍길동";
const greeting = `안녕하세요, ${name}!`;
console.log(greeting); // 안녕하세요, 홍길동!
태그 함수를 사용해 템플릿 리터럴을 커스터마이징
function formatMessage(strings, ...values) {
return strings.reduce((result, str, i) => {
return `${result}${str}${values[i] ? `<b>${values[i]}</b>` : ""}`;
}, "");
}
const taggedMessage = formatMessage`안녕하세요, ${customerName}님.
주문하신 ${orderItem}의 가격은 ${orderPrice.toLocaleString()}원입니다.`;
console.log(taggedMessage);
배열이나 객체에서 값을 쉽게 추출할 수 있는 문법
const arr = [1, 2, 3];
const [a, b] = arr;
console.log(a, b); // 1 2
const obj = { x: 1, y: 2 };
const { x, y } = obj;
console.log(x, y); // 1 2
import와 export 키워드를 사용하여 모듈을 정의하고 사용
<!-- export (파일 내보내기) -->
// module.js
export const PI = 3.14;
export function add(a, b) {
return a + b;
}
<!-- import (파일 가져오기) -->
// main.js
import { PI, add } from './module.js';
console.log(PI); // 3.14
console.log(add(2, 3)); // 5
import * as Utils from './04_module.mjs';
console.log(Utils.greet('Alice')); // Hi, Alice!
console.log(Utils.farewell('Alice')); // Goodbye, Alice!
객체 지향 프로그래밍을 지원하기 위해 클래스 문법을 도입
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`안녕하세요, 저는 ${this.name}입니다.`);
}
}
const person = new Person("홍길동", 30);
person.greet(); // 안녕하세요, 저는 홍길동입니다.
배열이나 객체의 요소를 펼쳐서 복사하거나 병합할 때 사용
// 배열 복사와 병합
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];
console.log(arr2); // [1, 2, 3, 4, 5]
// 객체 복사와 병합
const obj1 = { name: "홍길동", age: 30 };
const obj2 = { ...obj1, job: "개발자" };
console.log(obj2); // { name: "홍길동", age: 30, job: "개발자" }
let obj = {
prop0: 'p0',
prop1: 'p1',
prop2: 'p2'
};
let [a, ...rest] = [1, 2, 3];
console.log(rest); // [2,3]
let {prop1, ...restObj} = {prop1: 'a', prop2: 'b', prop3: 'c'};
console.log(restObj); // {prop2: 'b', prop3: 'c'}
배열이나 객체의 값을 개별 변수로 쉽게 추출
// 배열 구조 분해
const [a, b, c] = [1, 2, 3];
console.log(a, b, c); // 1, 2, 3
// 객체 구조 분해
const { name, age } = { name: "홍길동", age: 25 };
console.log(name, age); // 홍길동, 25
const [firstOrder, ...remainingOrders] = newOrders;
console.log(firstOrder); // 노트북
console.log(remainingOrders); // [스마트폰, 태블릿, 모니터]
java : sout-> javascript : console.log();
console.log(`문자열 ${변수명}`);
<!-- 출력 : 문자열 변수의값 -->
<!-- ``은 문자열 내부에 변수들을 삽입할 수 있다. -->
window -> vscode 코드 실행 방법 : ctrl + alt + n
reduce()
array.reduce((누적값, 현재값) => {
return 누적값 + 현재값;
}, 초기값);