본문 바로가기

Today I Learned

모던 자바스크립트 Deep Dive 21장 빌트인 객체

🔑 키워드 정리

  • 자바스크립트 실행 환경 : 브라우저 환경이나 Node.js 환경을 말한다.

📗 내용 정리

자바스크립트 객체의 분류

  • 표준 빌트인 객체

ECMAScript 사양에 정의된 객체. 브라우저 환경이건 Node.js 환경이건 자바스크립트 실행 환경에 관계없이 언제나 사용할 수 있다.

  • 호스트 객체

자바스크립트 실행 환경에서 제공하는 객체. 브라우저 환경에서는 DOM, BOM, Canvas, XMLHttpRequest, fetch... 등등 클라이언트 사이드 Web API를 호스트 객체로 제공한다. Node.js 환경에서는 Node.js 고유의 API를 호스트 객체로 제공한다.

  • 사용자 정의 객체

사용자가 직접 정의한 객체

표준 빌트인 객체

자바스크립트는 40여 개의 표준 빌트인 객체를 제공한다. Math, Reflect, JSON을 제외한 객체는 모두 인스턴스를 생성할 수 있는 생성자 함수 객체다.

Number.prototype 은 다양한 기능의 빌트인 프로토타입 메서드를 제공한다. 이 메서드는 모든 Number 인스턴스에 상속된다. Number은 표준 빌트인 객체 자체로 인스턴스 없이 정적 메서드를 호출할 수 있다.

const numberObj = new Number(1.5);
// Number.prototype의 메서드인 toFixed()
number.toFixed();


// Number의 정적 메서드는 isInteger()
Number.isInteger(0.5);

원시값과 래퍼 객체

원시값은 객체가 아니고 메서드도 가지지 않는다고 앞서 배웠다. 그러나 원시값은 객체처럼 프로퍼티나 메서드를 호출할 수 있다. 이는 자바스크립트 엔진이 일시적으로 원시값을 연관된 객체로 변환해주기 때문이다. 이때 임시 생성되는 객체를 래퍼 객체(String, Number, Boolean 등 빌트인 함수)라고 한다.

원시값인 문자열은 본래 length 프로퍼티나 toUpperCase 메서드를 가지고 있지 않다.

const str = 'hello';

console.log(str.length);
console.log(str.toUpperCase());

이처럼 문자열에 객체처럼 접근하면 래퍼 객체가 생성되어서 프로퍼티나 메서드를 호출한다. 그리고 래퍼 객체의 처리가 종료되면 식별자를 다시 원시값으로 되돌리고 래퍼 객체는 가비지 컬렉션의 대상이 된다.

String, Number, Boolean 생성자 함수는 new 연산자와 함께 호출할 필요가 없다. null, defined는 레퍼 객체를 생성하지 않는다!

전역 객체

전역 객체 = 어떤 객체에도 속하지 않은 최상위 객체. 표준 빌트인 객체와 호스트 객체를 프로퍼티로 소유한다. 브라우저 환경에서는 window, Node.js 환경에선는 global이 전역 객체를 가리킨다. ES11에서는 이를 globalThis 식별자로 통일했다.

특징

  • 개발자가 의도적으로 생성할 수 없다. 전역 객체의 생성자 함수가 제공될 수 없다.
  • 전역 객체의 프로퍼티를 참조할 때 window/global을 생략할 수 있다.
  • var 키워드로 선언한 전역 변수와 변수를 선언하지 않으면 암묵적 전역의 경우 전역 객체의 프로퍼티가 된다. 아래와 같이 접근 가능하다.
var foo = 1;
console.log(window.foo);

bar = 2;
console.log(window.bar);
  • let이나 const 키워드로 선언한 적연변수는 전역 객체의 프로퍼티가 아니다. window.foo로 접근 불가.
let foo = 1;
console.log(window.foo); // undefined

빌트인 전역 프로퍼티

전역 객체의 프로퍼티로, 애플리케이션 전역에서 사용한다.

  • Infinity : 무한대를 나타내는 숫자값
  • NaN : Not-a-Number의 약자. Number.NaN 프로퍼티와 같다.
  • undefined : 원시 타입 undefined

빌트인 전역 함수

애플리케이션 전역에서 호출할 수 있는 빌트인 함수.

  • eval

문자열 코드를 전달받아서 결과값을 리턴한다. 인수가 표현식이라면 런타임에 값을 생성하고 표현식이 아닌 문이라면 문자열 코드를 런타임에 실행한다.

eval('1+2'); // 3
eval('var a = 1;'); // undefined

기존의 스코프를 런타임에 동적으로 수정한다. strict mode에서는 수정하지 않고 자신만의 스코프를 생성한다. let, const 키워드를 사용한 변수는 암묵적으로 strict mode가 적용된다.

const x = 1;

function foo(){
	eval('var x = 2;');
	console.log(x); // 2
}
foo();

console.log(x); // 1

eval 함수는 보안에 취약하며 최적화가 되지 않아 처리 속도가 느리기 때문에 사용을 금지해야한다.

  • isFinite

인수가 유한수인지 확인하고 결과를 반환한다. *null을 숫자로 반환하면 0이 된다.

  • isNaN

인수가 NaN인지 검사하여 불리언 타입으로 반환한다.

  • parseFloat

인수를 실수로 해석하여 반환한다.

  • parseInt

첫번째 인수를 정수로 해석하여 반환한다. 두번째 인수로 해석할 진법을 정할 수 있다.

  • encodeURI/decodeURI

출처 https://hakawati.co.kr/

완전한 URI를 전달받아서 이스케이프 처리를 위해 인코딩한다. 이스케이프 처리란 네트워크를 통해서 정보를 공유할 때 어떤 시스템에서도 읽을 수 있게 아스키 문자 셋으로 변환하는 것이다. 한글, 공백, '%, ?, #'와 같은 문자열을 변환한다.

const uri = "https://example.com?name=테스트";
const enc = encodeURI(uri);
console.log(enc); //https://example.com?name=%ED%85%8C%EC%8A%A4%ED%8A%B8
 
  • encodeURIComponent/decodeURIComponent

URI 구성요소를 인수로 전달받아서 인코딩한다. 인수를 쿼리 스트링의 일부라고 간주하기 때문에 =, ?, & 까지 인코딩한다.

암묵적 전역

var x = 10; // 전역변수 x

function foo(){
// 선언하지 않은 식별자에 값을 할당.
y = 20; // window.y = 20; 전역 객체의 프로퍼티 y
}

console.log(x+y); // 30

y = 20;가 실행되면 참조에러가 발생할 것 같지만 그렇지 않다. 선언하지 않은 식별자에 값을 할당하면 전역 객체의 프로퍼티가 된다. y는 변수가 아니므로 변수 호이스팅이 발생하지 않는다. 또한 프로퍼티이기 때문에 delete 연산자로 삭제할 수 있다.