JavaScript의 모든 객체는 기원에 따라 두 가지로 분류됩니다:
구분 | 네이티브 객체 | 호스트 객체 |
---|---|---|
기원 | JavaScript 언어 자체 | 실행 환경 (브라우저, Node.js 등) |
표준 | ECMAScript 사양 정의 | 환경별 API 제공 |
호환성 | 모든 JS 환경에서 동일 | 환경에 따라 상이 |
독립성 | 플랫폼 독립적 | 플랫폼 종속적 |
// ✅ 네이티브 객체들 - 어디서든 동일하게 작동
const arr = new Array(); // JavaScript 표준
const obj = new Object(); // JavaScript 표준
const date = new Date(); // JavaScript 표준
// 🌐 호스트 객체들 - 환경에 따라 다름
// 브라우저에서만:
const xhr = new XMLHttpRequest(); // 브라우저 제공
console.log(window.location); // 브라우저 제공
// Node.js에서만:
// const fs = require('fs'); // Node.js 제공
// process.env.NODE_ENV; // Node.js 제공
네이티브 객체는 ECMAScript 사양에 정의된 JavaScript 언어 자체의 객체들입니다.
⚠️ 용어 주의사항
네이티브 객체를 Global Objects라고도 하지만, 전역 객체(Global Object)와는 다른 개념입니다!
- 전역 객체: 최상위 객체 (브라우저:
window
, Node.js:global
)- 네이티브 객체: JavaScript 표준에서 제공하는 모든 객체들
// Object - 모든 객체의 최상위
const obj = new Object();
console.log(obj.constructor === Object); // true
// Array - 배열 처리
const arr = [1, 2, 3];
console.log(arr.length); // 3
arr.push(4); // [1, 2, 3, 4]
// String - 문자열 처리
const str = "Hello World";
console.log(str.toUpperCase()); // "HELLO WORLD"
console.log(str.slice(0, 5)); // "Hello"
// Number - 숫자 처리
const num = 42.567;
console.log(num.toFixed(2)); // "42.57"
console.log(Number.isInteger(42)); // true
// Boolean - 논리값 처리
const bool = new Boolean(false);
console.log(Boolean(0)); // false
console.log(Boolean("hello")); // true
// Date - 날짜와 시간
const now = new Date();
console.log(now.getFullYear()); // 2024
console.log(now.toLocaleDateString()); // "2024/8/8"
const specificDate = new Date('2024-12-25');
console.log(specificDate.getDay()); // 요일 (0-6)
// RegExp - 정규 표현식
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
console.log(emailRegex.test("user@example.com")); // true
const phoneRegex = new RegExp('^\\d{3}-\\d{4}-\\d{4}$');
console.log(phoneRegex.test("010-1234-5678")); // true
// Promise - 비동기 처리
const fetchData = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("데이터 로드 완료! 🎉");
}, 1000);
});
fetchData.then(data => console.log(data));
// Map - 키-값 쌍 컬렉션
const userMap = new Map();
userMap.set('name', 'John');
userMap.set(1, 'first');
userMap.set(true, 'boolean key');
console.log(userMap.get('name')); // "John"
console.log(userMap.size); // 3
// Set - 유일한 값들의 컬렉션
const uniqueNumbers = new Set([1, 2, 2, 3, 3, 4]);
console.log([...uniqueNumbers]); // [1, 2, 3, 4]
uniqueNumbers.add(5);
console.log(uniqueNumbers.has(3)); // true
// Math - 수학 함수들 (정적 객체)
console.log(Math.PI); // 3.141592653589793
console.log(Math.random()); // 0~1 사이 랜덤값
console.log(Math.max(1, 5, 3)); // 5
console.log(Math.floor(4.7)); // 4
// Error - 오류 처리
try {
throw new Error("사용자 정의 오류 발생!");
} catch (error) {
console.log(error.name); // "Error"
console.log(error.message); // "사용자 정의 오류 발생!"
}
// 특정 에러 타입들
const typeError = new TypeError("타입 오류");
const rangeError = new RangeError("범위 오류");
const referenceError = new ReferenceError("참조 오류");
호스트 객체는 JavaScript가 실행되는 런타임 환경에서 제공하는 객체들입니다.
// Window - 브라우저 전역 객체
console.log(window.innerWidth); // 브라우저 창 너비
console.log(window.location.href); // 현재 URL
window.alert("안녕하세요! 👋");
// Document - DOM 조작
const title = document.querySelector('h1');
title.textContent = "새로운 제목";
document.body.style.backgroundColor = '#f0f0f0';
// Navigator - 브라우저 정보
console.log(navigator.userAgent); // 브라우저 정보
console.log(navigator.language); // "ko-KR"
console.log(navigator.onLine); // 온라인 상태
// XMLHttpRequest - AJAX 통신
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log("데이터 수신 완료:", xhr.responseText);
}
};
xhr.send();
// Storage - 로컬 저장소
localStorage.setItem('username', 'john');
sessionStorage.setItem('theme', 'dark');
console.log(localStorage.getItem('username')); // "john"
console.log(sessionStorage.getItem('theme')); // "dark"
// Console - 디버깅 (브라우저 제공)
console.log("일반 로그");
console.error("에러 메시지 🚨");
console.warn("경고 메시지 ⚠️");
console.table([{name: 'John', age: 30}]);
// Process - 프로세스 정보
console.log(process.version); // Node.js 버전
console.log(process.platform); // 운영체제 정보
console.log(process.env.NODE_ENV); // 환경 변수
process.on('exit', (code) => {
console.log(`프로세스 종료: ${code}`);
});
// Global - Node.js 전역 객체
global.myGlobalVar = "전역 변수";
console.log(global.myGlobalVar);
// Buffer - 바이너리 데이터 처리 (Node.js 특화)
const buffer = Buffer.from('Hello World', 'utf8');
console.log(buffer.toString('base64')); // SGVsbG8gV29ybGQ=
// 모듈 시스템 관련
console.log(__dirname); // 현재 디렉토리
console.log(__filename); // 현재 파일명
// 타이머 함수들 (Node.js에서 전역으로 제공)
const immediate = setImmediate(() => {
console.log("즉시 실행");
});
const timeout = setTimeout(() => {
console.log("1초 후 실행");
}, 1000);
기능 | 브라우저 | Node.js | 공통 여부 |
---|---|---|---|
전역 객체 | window | global | ❌ |
타이머 | window.setTimeout | global.setTimeout | ✅ (구현 다름) |
콘솔 | window.console | global.console | ✅ (기능 다름) |
DOM | document | ❌ | ❌ |
HTTP | XMLHttpRequest | http 모듈 | ❌ |
파일 시스템 | ❌ | fs 모듈 | ❌ |
저장소 | localStorage | ❌ | ❌ |
// ✅ 환경 감지 후 적절한 객체 사용
function getGlobalObject() {
// 브라우저 환경
if (typeof window !== 'undefined') {
return window;
}
// Node.js 환경
if (typeof global !== 'undefined') {
return global;
}
// Web Worker 환경
if (typeof self !== 'undefined') {
return self;
}
throw new Error('지원되지 않는 환경입니다.');
}
// 사용법
const globalObj = getGlobalObject();
globalObj.myApp = { version: '1.0.0' };
function getObjectType(obj) {
// 네이티브 객체인지 확인
const nativeObjects = [
'Object', 'Array', 'String', 'Number', 'Boolean',
'Date', 'RegExp', 'Promise', 'Map', 'Set', 'Error'
];
const objectType = Object.prototype.toString.call(obj).slice(8, -1);
if (nativeObjects.includes(objectType)) {
return `네이티브 객체: ${objectType}`;
}
// 호스트 객체 판별
if (typeof window !== 'undefined') {
if (obj === window) return '호스트 객체: Window';
if (obj === document) return '호스트 객체: Document';
if (obj instanceof XMLHttpRequest) return '호스트 객체: XMLHttpRequest';
}
if (typeof global !== 'undefined') {
if (obj === process) return '호스트 객체: Process';
if (obj === global) return '호스트 객체: Global';
}
return `사용자 정의 객체: ${objectType}`;
}
// 테스트
console.log(getObjectType([])); // "네이티브 객체: Array"
console.log(getObjectType(new Date())); // "네이티브 객체: Date"
console.log(getObjectType({})); // "네이티브 객체: Object"
if (typeof window !== 'undefined') {
console.log(getObjectType(window)); // "호스트 객체: Window"
}
// ❌ 잘못된 방법: 환경 체크 없이 사용
try {
localStorage.setItem('data', 'value'); // Node.js에서 오류!
} catch (error) {
console.error("localStorage를 사용할 수 없습니다.");
}
// ✅ 올바른 방법: 환경 체크 후 사용
function saveData(key, value) {
// 브라우저 환경
if (typeof localStorage !== 'undefined') {
localStorage.setItem(key, value);
return '브라우저 localStorage에 저장됨';
}
// Node.js 환경
if (typeof require !== 'undefined') {
const fs = require('fs');
fs.writeFileSync(`${key}.json`, JSON.stringify(value));
return '파일 시스템에 저장됨';
}
return '저장할 수 없는 환경입니다.';
}
console.log(saveData('userData', { name: 'John', age: 30 }));
// Promise 폴리필 예시 (구형 브라우저 지원)
if (typeof Promise === 'undefined') {
// Promise 폴리필 라이브러리 로드
// 또는 간단한 구현 제공
console.log('Promise 폴리필이 필요합니다.');
}
// fetch API 포니필 예시
if (typeof fetch === 'undefined') {
// 브라우저: fetch 폴리필
// Node.js: node-fetch 라이브러리 사용
if (typeof window !== 'undefined') {
console.log('fetch 폴리필을 로드하세요.');
} else {
console.log('node-fetch를 설치하세요: npm install node-fetch');
}
}
구분 | 네이티브 객체 | 호스트 객체 |
---|---|---|
정의 | ECMAScript 표준 제공 | 실행 환경에서 제공 |
사용 범위 | 모든 JavaScript 환경 | 특정 환경에서만 |
예시 | Array, Object, Promise | window, document, process |
안정성 | 표준 보장 | 환경별로 다름 |
성능 | 최적화됨 | 환경에 따라 다름 |
// 🎯 범용 유틸리티 함수 작성
const utils = {
// 환경별 로그 함수
log: (typeof console !== 'undefined')
? console.log.bind(console)
: () => {},
// 환경별 타이머 함수
delay: (ms) => new Promise(resolve =>
setTimeout(resolve, ms)
),
// 환경 감지
isBrowser: typeof window !== 'undefined',
isNode: typeof process !== 'undefined' && process.versions?.node,
// 안전한 JSON 파싱
safeJSONParse: (str) => {
try {
return JSON.parse(str); // 네이티브 객체 사용
} catch (error) {
utils.log('JSON 파싱 실패:', error.message);
return null;
}
}
};