
JS 자체적으로 개발자들에게 아주 유용한 기능을 모아놓은, 이미 내장되어있는 객체
별도 정의 없이 즉시 사용 가능
각 객체가 보유한 속성과 메서드는 API문서 참고하여 개발에 적용
API 문서: 속성과 메서드의 목록과 사용법을 정리해둔 참조 문서
내장 객체가 API의 구성 요소
(API가 자판기 버튼이라면, 내장 객체는 자판기 안의 음료수)
| 객체 이름 | 분류 |
|---|---|
| Object | 기본 객체 |
| Array | 배열 관련 |
| Number | 숫자 관련 |
| Math | 수학 관련 |
| String | 문자열 관련 |
| Date | 날짜 관련 |
| JSON | 데이터 표현 |
| Error | 예외 처리 |
✅ API 쉽게 설명
API는 프로그램이나 서비스가 다른 프로그램과 상호작용할 수 있도록 하는 "기능의 문을 열어주는 버튼"
비유: 자판기 예시
자판기는 우리가 음료수를 사고 싶을 때 버튼을 눌러 음료를 얻을 수 있는 기계입니다.
자판기에는 음료 목록, 가격, 버튼 등 여러 가지가 있지만, 우리는 음료를 고르고 버튼을 누르는 것만 알면 됩니다.
자판기의 내부 동작은 모르지만, 음료는 잘 나오죠. 이처럼 우리는 자판기의 복잡한 내부를 몰라도 음료를 쉽게 받을 수 있습니다.
API도 마찬가지입니다!
API는 어떤 프로그램이나 서비스가 외부와 소통할 수 있도록 만든 기능(버튼)입니다.
우리가 어떤 기능(예: 데이터를 가져오기, 계산하기 등)을 사용할 때, 그 기능을 제공하는 시스템의 복잡한 내부 동작은 몰라도 쉽게 사용할 수 있게 도와주는 인터페이스입니다.
예시: 음악 앱의 API
여러분이 좋아하는 음악을 들으려면, 음악 앱에 들어가서 곡을 선택하고 플레이해야 합니다.
하지만 이 앱은 음악을 제공하는 서버와 소통해야 해요.
여기서 API는 음악 앱과 서버 간의 대화 방법을 정의하는 역할을 합니다.
예: "이 노래를 재생해 주세요"라는 요청을 API가 서버에 전달하고, 서버는 "이 노래를 재생할 수 있습니다"라고 응답합니다.
Date 객체 : 날짜와 시간을 처리하기 위한 내장 객체 📆⏰
'Sat May 10 2025 18:01:28 GMT+0900 (한국 표준시)' 형태의 날짜와 시간 출력
let test=function(){
let d=new Date();
console.log(d); //한국 표준시로 출력
console.log(d.getFullYear(),d.getMonth()+1,d.getDate(),d.getDay(),d.getHours(),d.getMinutes(),d.getSeconds());
// ⚠ 월은 0부터 시작."사람이 보는 월"로 출력하려면+1 → getMonth()+1해줘야함
// getDay() 요일, 한 주의 시작은 0=Sunday
}
// setInterval의 첫번째 매개변수로 함수를 넘겨줄 때
// 호출이 아닌 함수명 또는 함수정의가 와야함
// 만일 함수()써서 넘겨버리면, setInterval에게 호출을 맡기는게 아니라 바로 호출이 되어버림
setInterval(test,1000); // "setInterval아 1초마다 내가 정의한 test함수 호출해줘"

<head>
<title>시계만들기</title>
<style>
#hour,#min,#sec{
font-size: 80px;
color: palevioletred;
background-color: blanchedalmond;
width: 120px;
height: 120px;
border: 2px solid gray;
border-radius: 3px;
display: inline-block; /* 나란히 세워주기 */
text-align: center;
}
</style>
<script src="../js_lib/common.js"></script>
<script>
let showTime=function(){
//표현식에 의한 함수정의 (함수를 데이터처럼 변수로 받을 수 있다, 일급시민)
let d=new Date();
let h=d.getHours(); //시간만 추출
let hour=document.getElementById("hour");
hour.innerText=zeroString(h) // js_lib/common.js에서 함수꺼내쓰기
let m=d.getMinutes(); //분만 추출
let min=document.getElementById("min");
min.innerText=zeroString(m) // js_lib/common.js에서 함수꺼내쓰기
let s=d.getSeconds(); //초만 추출
let sec=document.getElementById("sec");
sec.innerText=s;
if(s>=0 && s<10)sec.innerText="0"+s; // 한자리 수 앞에 0붙여주기
}
addEventListener("load",()=>{
setInterval(showTime,1000);
});
</script>
</head>
<body>
<div id="hour"></div>
<div id="min"></div>
<div id="sec"></div>
</body>
//한 자리 수 숫자 n 앞에 0을 붙여주기
function zeroString(n){
let str=n;
if(n>=0 && n<10)str="0"+n;
return str;
}

달력이 이따구...지만 일단 로직이 중요하니까 ^^
border 줬을 때 Cell 크기와 전체 틀의 크기가 안 맞아서
어긋나는 현상 개선
➡️ CSS의 boxSizing="border-box" (안쪽으로 살찌우기)
다이어리
자주 쓸 함수들은 라이브러리에 정의해두자
// 해당 월의 '시작 요일' 구하기
// API 사용 예) 2025년 5월 → getStartDay(2025,4)
function getStartDay(yy,mm){
let d = new Date(yy,mm,1); // 1일
return d.getDay(); // 요일을 반환
}
/*-----------------------------------------------------------------*/
// 영어 또는 한국어로 요일을 변환하여 반환하기
// API 사용 예) convertDay(2,"eng")
function convertDay(n,lang){
let korArray=["일요일","월요일","화요일","수요일","목요일","금요일","토요일"];
let engArray=["Sun","Mon","Tue","Wed","Thur","Fri","Sat"];
//어떤 요일을 선책할 지 결정
let day=(lang=="kor")? korArray[n]:engArray[n];
return day;
}
/*-----------------------------------------------------------------*/
// 해당 월의 "마지막 날" 구하기 (= 다음 달의 시작 일 하루 전)
// API 사용 예) getLastDate(원하는 연도, 원하는 월-1)
function getLastDate(yy,mm){
let d = new Date(yy,mm+1,0);
return d.getDate();
}
<script src="../js_lib/common.js"></script> //자주 쓸 함수 모아놓은 라이브러리 파일
<script src="./js/Cell.js"></script> //달력을 이루는 하나의 셀 정의한 클래스
<script>
let cellWidth=100; //각 셀의 너비
let cellHeight=100; //각 셀의 높이
let border=1; //셀의 보더 두께
let currentYear; //유저가 현재 보게 될 연도 , 로드 시에도 할당, 다음, 이전 버튼 누를 때도 할당
let currentMonth; //유저가 현재 보게 될 월
let cellArray=[]; //셀 생성 후 제어하려면 이름 필요->변수 필요하다
//하지만 변수명 일일이 다르게 주면 규칙 없으므로 배열로 가자
function createCell(){
// 위의 크기정보로 wrapper의 크기를 동적으로 계산할 수 있다! (전에 고민했던 부분
wrapper.style.width=(cellWidth+(border*3))*7+"px"; //안먹혀서 일단 border*3
wrapper.style.height=(cellHeight+(border*2))*6+40+50+"px";
//요일 영역 출력
for(let i=0; i<7; i++){
let cell=new Cell(document.getElementById("days"),cellWidth,40,"yellow",1,"black",convertDay(i,"kor"));
}
for(let a=0; a<6; a++){ //6층 (최대6줄 필요함)
for(let i=0; i<7; i++){ //7호수 (일주일)
let cell=new Cell(document.getElementById("section"),cellWidth,cellHeight,"white",border,"black","");
cellArray.push(cell);
}
}
}
//모든 셀의 innerText스트링을 지워버리자
function clearDate(){
let index=0;
for(let a=0; a<6; a++){
for(let i=0; i<7; i++){
cellArray[index++].div.innerText="";
}
}
}
// 이미 생성된 셀에 날짜를 출력한다 (날짜 출력 전용 함수)
// 주의) 다음,이전 버튼을 누르면 기존에 셀에 출력된 날짜는 지우고, 새로운 날짜를 출력
function printDate(){
let count=0; //셀의 인덱스, 박스의 순번 (날짜 아님!)
let n=0; //유저가 보게될 달력의 날짜
for(let a=0; a<6; a++){
for(let i=0; i<7; i++){
let cell=cellArray[count]; //셀 하나 꺼내기
if(count >= getStartDay(currentYear, currentMonth) && n < getLastDate(currentYear,currentMonth)){
// (n <= getLastDate())하면 마지막 날 다음 숫자까지 출력됨 (오류 발생)
n++; //1씩 증가를 count가 해당월의 시작일을 만나는 순간부터 하자
cell.div.innerText=n;
}
count++;
}
}
}
// 현재 날짜 얻어오기
function getCurrentDate(){
let d=new Date();
currentYear=d.getFullYear();
currentMonth=d.getMonth();
}
// 헤더 영역에 현재 보고있는 날짜 출력 (년,월)
function printTitle(yy,mm){
//다음,이전 버튼 누를 때 마다 호출할 것이므로 년,월 매개변수로 설정
let d=new Date(yy,mm);
currentYear=d.getFullYear();
currentMonth=d.getMonth();
let h2=document.querySelector("#header h2");
h2.innerText=`${currentYear}년 ${currentMonth+1}월`
}
// 참고) 이벤트 리스너의 두번째 매개변수로 들어가야하는 함수는
// 정의를 해야하지 호출해서는 안된다.
// 두번째 매개변수에 등록되는 함수는 개발자가 호출하는 함수가 아니라
// 브라우저가 load이벤트 발생시 거꾸로 호출을 해주는 역할을 하므로
// callback함수라 부른다.
addEventListener("load", function(){
//현재 날짜를 제목에 출력부터 해주자
getCurrentDate(); // 직접적으로 화면에 뭘 보여주진 않음
// 하지만 화면에 보여줄 정보를 준비하는 역할
createCell();
printTitle(currentYear,currentMonth);
printDate(currentYear,currentMonth);
//현재 보고있는 월의 시작요일을 조사해보자
getStartDay(currentYear,currentMonth);
//달력의 제목을 이전,다음 버튼으로 바꾸자
let bt_prev=document.querySelector("#header :nth-child(1)");
let bt_next=document.querySelector("#header :nth-child(3)");
bt_prev.addEventListener("click",function(){
currentMonth--;//이전 월로 설정
printTitle(currentYear,currentMonth); //년도 계산 필요x Date내장객체가 알아서 계산함
clearDate();
printDate(currentYear,currentMonth);
});
bt_next.addEventListener("click",function(){
currentMonth++;//이전 월로 설정
printTitle(currentYear,currentMonth); //년도 계산 필요x Date내장객체가 알아서 계산함
clearDate();
printDate(currentYear,currentMonth);
});
});
</script>
초기 실행 (window load 시점)
getCurrentDate() → 오늘 날짜(연, 월)를 전역 변수 currentYear, currentMonth에 저장
createCell() → 요일과 날짜 셀을 동적으로 생성해서 DOM에 추가 (cellArray에 저장)
printTitle(currentYear, currentMonth) → 현재 연/월을 상단 제목에 출력
printDate(currentYear, currentMonth) → 셀에 해당 월의 날짜를 출력
셀 생성 (createCell)
wrapper의 크기 동적으로 설정
요일 셀 7개 출력 (라이브러리에 만들어둔convertDay(i,"kor") 이용)
날짜 셀 6x7=42개 생성 → cellArray에 저장
날짜 출력 (printDate)
날짜는 몇 번째 셀부터 출력할지 getStartDay(연, 월)로 확인 (이건 요일값 return)
그 다음부터 날짜 n을 1씩 증가시켜 출력
마지막 날짜는 getLastDate(연, 월)로 확인 (이건 날짜값 return)
이전/다음 버튼 클릭 시 흐름
currentMonth를 증가 또는 감소
printTitle()로 새로운 년/월을 헤더에 출력 (내장 Date 객체가 자동 계산)
clearDate()로 기존 셀의 날짜 제거(innerText스트링=" "로 제거)
printDate()로 새 날짜 출력
기타 보조 함수들
getCurrentDate() → 현재 날짜 정보 가져옴
printTitle(yy, mm) → 헤더의 h2 태그에 년 월 출력
clearDate() → cellArray의 innerText를 전부 ""로 초기화
└ getCurrentDate() → createCell() → printTitle() → printDate()
└ currentMonth 조정 → printTitle() → clearDate() → printDate()
❓ getCurrentDate()랑 printTitle() 둘 다 currentYear, currentMonth 값을 바꾸고 있음.
같은 변수 두 번 바꾸는 거면 중복 아닌가?
❕ 중복되는 건 맞지만, "의도된 중복"임.
각 함수가 다른 타이밍에 같은 전역 상태값을 관리해야 하기 때문
| 함수 이름 | 언제 실행됨 | currentYear, currentMonth |
|---|---|---|
getCurrentDate() | 시작할 때 | "지금 기준"으로 달력 정보 설정 |
printTitle() | 버튼 눌렀을 때 | "유저가 보고 있는 기준"으로 달력 정보 설정 |
변수 이름은 같지만,
상황에 따라 다른 의미로 쓰이니까, 사실상 "다른 역할"
단지 변수 이름을 바꾸지 않고 계속 재활용하고 있는 것.
<더 알아보기>
| 용어 | 설명 |
|---|---|
| 클래스 | 객체를 만들기 위한 설계도 |
| 객체 | 클래스에 따라 만들어진 실체 (데이터 + 기능) |
| 인스턴스 | 어떤 클래스에서 실제로 만들어진 객체 → "객체 = 인스턴스" |
→ 즉, 객체 = 인스턴스지만, 인스턴스라는 말은 클래스와의 관계를 강조할 때 씀
PRIMARY KEY를 참조하는 컬럼원본(기준 데이터)을 가진 쪽 → 부모 테이블
참조하는 쪽 → 자식 테이블
부모 테이블의PRIMARY KEY를 자식 테이블이FOREIGN KEY로 가짐
-- 부모: 부서
CREATE TABLE DEPT (
DEPTNO NUMBER PRIMARY KEY,
DNAME VARCHAR2(20)
);
-- 자식: 사원
CREATE TABLE EMP (
EMPNO NUMBER PRIMARY KEY,
ENAME VARCHAR2(20),
DEPTNO NUMBER,
FOREIGN KEY (DEPTNO) REFERENCES DEPT(DEPTNO)
);
--JOIN 예제: 사원 이름과 그 사원이 속한 부서 이름 출력
--ANSI JOIN 문법
SELECT ENAME, DNAME
FROM EMP E
JOIN DEPT D ON E.DEPTNO = D.DEPTNO;
--ORACLE에서 많이 쓰이던 옛날 JOIN 방식
SELECT ENAME, DNAME
FROM EMP E, DEPT D
WHERE E.DEPTNO=D.DEPTNO
EMP.DEPTNO→ DEPT.DEPTNO 가 FOREIGN KEY 관계
FOREIGN KEY는 테이블 설계(DDL)에서 선언되고,--SCOTT이 근무하는 부서와 같은 부서에 근무하는 사원의 이름,급여,부서명,부서위치 출력
SELECT ENAME, SAL, DNAME, LOC
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO
AND E.DEPTNO = (SELECT DEPTNO FROM EMP WHERE ENAME = 'SCOTT');
<참고>
SQL*PLUS 자체명령 중 한 라인에 들어갈 글자 수 늘리기 : SET LINE 600
API나 쿼리, 프로그래밍 개념을 배우기 전에는 그냥 강사님이 하라고 하니까 따라 하기만 했는데, 이렇게 하나하나 개념을 확실히 잡고 나니 훨씬 더 효율적이고 이해도 높은 작업을 할 수 있게 되는 것 같다.
처음에는 "그냥 이렇게 하면 된다" 라고 해서 똑같이 따라가기 급급했던 것들이, 개념을 제대로 이해하고 나면 왜 이렇게 써야 하는지, 무엇을 더 고려해야 하는지까지 알게 되면서 한 단계 성장한 느낌이 부쩍 드는 요즘이다.