본문 바로가기

JavaScript

[Deep dive] 21장 빌트인 객체

21.1 자바스크립트 객체의 분류 

 

1) 표준 빌트인 객체 (standard built-in objects)

 

 - ECMAScript 사양에 정의된 객체 

 - 애플리케이션 전역의 공통 기능 제공

 - 자바스크립트 실행 환경과 관계없이 언제나 사용 가능

 - 표준 빌트인 객체는 전역 객체의 프로퍼티로서 제공

 

2) 호스트 객체 (host object)

 

- ECMAScript 사양에 정의되어 있지 않지만 자바스크립트 실행환경(브라우저, Node.js)에서 추가로 제공되는 객체 

- 브라우저 환경에서는 클라이언트 사이드 web API를 호스트 객체로 제공

- Node.js 환경에서는 Node.js 고유의 API를 호스트 객체로 제공

 

3) 사용자 정의 객체 (user-defined objects)

 

 - 사용자가 직접 정의한 객체 

 

 

21.2 표준 빌트인 객체 

 

표준 빌트인 객체 

- Object, String, Number, Boolean, Symbol, Date, Math, RegExp, Array, Map/Set, WeakMap/WeakSet,

Function, Promise, Reflect, Proxy, Json, Error 등 40 여개 

 

- Math, Reflect, Json을 제외한 표준 빌트인 객체는 모두 인스턴스를 생성할 수 있는 생성자 함수 객체 

 

- 생성자 함수 객체인 표준 빌트인 객체는 프로토타입 메서드와 정적 메서드 제공

- 생성자 함수 객체가 아닌 표준 빌트인 객체는 정적 메서드만 제공

 

- 표준 빌트인 객체인 String, Number, Boolean, Function, Array, Date는 생성자 함수로 호출하여 인스턴스 생성 가능

- 생성자 함수인 표준 빌트인 객체가 생성한 인스턴스의 프로토타입은 표준 빌트인 객체의 prototype 프로퍼티에 바인딩된 객체 

//String 생성자 함수에 의한 String 객체 생성
const strObj = new String('Lee'); 

//String 생성자 함수를 통해 생성한 strObj 객체의 프로토타입은 String.prototype이다
console.log(Object.getPrototypeOf(strObj) === String.prototype); //true

 

- 표준 빌트인 객체의 prototype 프로퍼티에 바인딩된 객체는 다양한 기능의 빌트인 프로토타입 메서드를 제공

- 표준 빌트인 객체는 인스턴스 없이도 호출 가능한 빌트인 정적 메서드 제공

//Number 생성자 함수에 의한 Number 객체 생성
const numObj = new Number(1.5); 

//toFixed는 Number.prototype의 프로토타입 메서드 
console.log(numObj.toFixed()); //2

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

 

21.3 원시값과 래퍼 객체 

 

래퍼 객체 (wrapper object)

 

-문자열, 숫자, 불리언 값에 대해 객체처럼 접근하면 생성되는 임시 객체 

 

ex)

-문자열에 대해 마침표 표기법으로 접근하면 그 순간 래퍼 객체인 String 생성자 함수의 인스턴스가 생성되고 문자열은 래퍼 객체의 [[StringData]] 내부 슬롯에 할당

 

- String 생성자 함수의 인스턴스는 String.prototype의 메서드를 상속받아 사용 가능

 

- 래퍼 객체의 처리가 종료되면 래퍼 객체의 [[StringData]] 내부 슬롯에 할당된 원시값으로 원래의 상태로 되돌리고 

래퍼 객체는 가비지 컬렉션의 대상이됨

 

const str = 'hi';

//원시 타입인 문자열이 래퍼 객체인 String 인스턴스로 변환
console.log(str.length);//2
console.log(str.toLocaleUpperCase()); //HI

//래퍼 객체로 프로퍼티에 접근하거나 메서드를 호출한 후, 다시 원시값으로 되돌림
console.log(typeof str); //string

 

21.4 전역 객체 

 

전역 객체(global object)

 

- 코드가 실행되기 이전 단계에서 자바스크립트 엔진에 의해 어떤 객체보다도 먼저 생성되는 특수한 객체 

- 어떤 객체에도 속하지 않은 최상위 객체 

- 브라우저 환경에서는 window(또는 self, this,frames)가 전역객체를 가리킴

- Node.js 환경에서는 global이 전역 객체를 가리킴

 

- 전역 객체를 생성할 수 있는 생성자 함수가 제공되지 않음

- 전역 객체의 프로퍼티를 참조할 때 window(global) 생략 가능

 

- 전역 객체는 모든 표준 빌트인 객체를 프로퍼티로 가지고 있음

- 환경에 따른 호스트 객체를 가짐 

 

-var 키워드로 선언한 전역 변수와 선언하지 않은 변수에 값을 할당한 암묵적 전역, 그리고 전역함수는 전역 객체의 프로퍼티가 됨

//var 키워드로 선언한 전역 변수 
var foo =1;
console.log(window.foo); //1

//암묵적 전역. bar는 전역 변수가 아니라 전역 객체의 프로퍼티 
bar = 2; //window.bar =2
console.log(window.bar); //2

//전역 함수 
function baz() { return 3;}
console.log(window.baz()); //3

- let이나 const 키워드로 선언한 전역 변수는 전역 객체의 프로퍼티가 아니다.

- let이나 const 키워드로 선언한 전역 변수는 보이지 않는 개념적인 블록 (전역 렉시컬 환경의 선언적 환경 레코드) 내에 존재

let foo =123;
console.log(window.foo); //undefined

 

- 브라우저 환경의 모든 자바스크립트 코드는 하나의 전역 객체 window를 공유 

 

 

21.4.1 빌트인 전역 프로퍼티 

 

- 애플리케이션 전역에서 사용하는 값 제공

 

1) Infinity

 

- Infinity 프로퍼티는 무한대를 나타내는 숫자값 Infinity를 가짐 

console.log(window.Infinity === Infinity); //true

//양의 무한대 
console.log(3/0); //Infinity

//음의 무한대 
console.log(-3/0); //-Infinity

//Infinity는 숫자값이다
console.log(typeof Infinity); //number

 

2) NaN

 

- NaN 프로퍼티는 숫자가 아님을 나타내는 숫자값 NaN을 가짐

console.log(window.NaN); //NaN

console.log(Number('xyz')); //NaN
console.log(1*'string'); //NaN
console.log(typeof NaN); //NaN

 

3) undefined

 

- undefined 프로퍼티는 원시 타입 undefined를 값으로 가짐

console.log(window.undefined); //undefined

var foo;
console.log(foo); //undefined
console.log(typeof undefined); //undefined

 

21.4.2 빌트인 전역 함수 

 

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

 

1) eval

 

- 자바스크립트 코드를 나타내는 분자열을 인수로 전달받음

- 전달받은 문자열 코드가 표현식이라면 eval 함수는 문자열 코드를 런타임에 평가하여 값을 생성

- 전달받은 인수가  표현식이 아닌 문이라면 eval 함수는 문자열 코드를 런타임에 실행 

//표현식인 문
eval('1+2'); //3
//표현식이 아닌 문
eval('var x = 5;'); //undefined

//eval 함수에 의해 런타임에 변수 선언문이 실행되어 x 변수가 선언됨
console.log(x); //5

//객체 리터럴은 반드시 괄호로 둘러쌈
const o = eval('([({a:1})])');
console.log(o); // {a:1}

//함수 리터럴은 반드시 괄호로 둘러쌈
const f = eval('(function() { return 1;})');
console.log(f()); //1

- eval 함수는 자신이 호출된 이치에 해당하는 기존의 스코프를 런타임에 동적으로 수정 

const x =1;

function foo() {
  //eval 함수는 런타임에 foo 함수의 스코프를 동적으로 수정
  eval('var x =2;');
  console.log(x); //2
}

foo();
console.log(x); //1

- strict mode에서 eval 함수는 기존의 스코프를 수정하지 않고 eval 함수 자신의 자체적인 스코프를 생성

- 인수로 전달받은 문자열 코드가 let,const 키워드를 사용한 변수 선언문이라면 암묵적으로 strict mode가 적용

 

- eval 함수를 통해 사용자로부터 입력받은 콘텐츠를 실행하는 것은 보안에 매우 취약하므로 eval 함수의 사용은 금지 

 

2) isFinite

 

- 전달받은 인수가 정상적인 유한수인지 검사하여 유한수이면 true 반환하고

- 무한수이면 false 반환

- 전달받은 인수의 타입이 숫자가 아닌 경우, 숫자로 타입 변환한 후 검사 수행

 

3) isNaN

 

- 전달받은 인수가 NaN인지 검사하여 그 결괄르 불리언 타입으로 반환

- 전달받은 인수의 타입이 숫자가 아닌 경우 숫자로 타입을 변환한 후 검사 수행

 

4) parseFloat

 

-전달받은 문자열 인수를 시룻로 해석(parsing)하여 반환

//문자열을 실수로 해석하여 반환
parseFloat('3.14'); //3.14
parseFloat('10.00'); //10.00

//공백으로 구분된 문자열은 첫 번째 문자열만 반환
parseFloat('34 45 66'); //34
parseFloat('40 years'); //40

//첫 번째 문자열을 숫자로 반환할 수 없다면 NaN을 반환
parseFloat('He was 40'); //NaN

//앞뒤 공백은 무시됨
parseFloat('  60  '); //60

 

5) parseInt

 

- 전달받은 문자열 인수를 정수로 해석하여 반환

- 두번째 인수로 진법을 나타내는 기수(2~36)전달 가능

- 기수를 지정하면 첫 번째 이누로 전달된 문자열을 해당 기수의 숫자로 해석하여 반환 (반환값은 언제나 10진수)

//문자열을 정수로 해석하여 반환
parseInt('10.123'); //10

//10을 2진수로 해석하고 그 결과를 10진수 정수로 반환
parseInt('10',2); //2
//10을 8진수로 해석하고 그 결과를 10진수 정수로 반환
parseInt('10',8); //8
//10을 16진수로 해석하고 그 결과를 16진수 정수로 반환
parseInt('10',16); //16

 

6) encodeURI / decodeURI

 

URI (Uniform Resource Identifier)

- 인터넷에 있는 자원을 나타내는 유일한 주소 

 

인코딩

- URI의 문자들을 이스케이프 처리하는 것

 

이스케이프 처리

- 네트워크를 통해 정보를 공유할 때 어떤 시스템에서도 읽을 수 있는 아스키 문자 셋으로 변환하는 것

 

encodeURI 함수 

- 완전한 URI를 문자열로 전달받아 이스케이프 처리를 위해 인코딩

- 퀴리 스트링 구분자로 사용되는 =,?,&는 인코딩하지 않음 

 

decodeURI 함수 

 - 인코딩된 URI를 인수로 전달받아 이스케이프 처리 이전으로 디코딩

const uri = 'http://example.com? name=이웅모&job=programmer&teacher'

//encodeURI 함수는 완전한 URI를 전달받아 이스케이프 처리를 위해 인코딩
const enc = encodeURI(uri);
console.log(enc);
//http://example.com?%20name=%EC%9D%B4%EC%9B%85%EB%AA%A8&job=programmer&teacher

//decodeURI 함수는 인코딩된 완전한 URI를 전달받아 이스케이프 처리 이전으로 디코딩함
const dec = decodeURI(enc);
console.log(dec);
//http://example.com? name=이웅모&job=programmer&teacher

 

7) encodeURIComponent / decodeURIComponet

 

 encodeURIComponent 함수

 - 인수로 전달된 문자열을 URI의 구성요소인 쿼리 스트링의 일부로 간주

 - 쿼리 스트링 구분자로 사용되는 =,?,&까지 인코딩 

 

 

21.4.3 암묵적 전역

 

//전역 변수 x는 호이스팅이 발생
console.log(x); //undefined
//전역 변수가 아니라 전역 객체의 프로퍼티인 y는 호이스팅이 발생하지 않음
console.log(y); //ReferenceError

var x = 10; //전역 변수 

function foo() {
  //선언하지 않은 식별자에 값을 할당
  y = 20; //window.y = 20
}
foo();

//선언하지 않은 식별자 y를 전역에서 참조할 수 있다
console.log(x+y); //30

- 암묵적 전역으로 선언된 y는 변수가 아니므로 변수 호이스팅이 발생되지 않음

- y는 단지 전역 객체의 프로퍼티로 추가되었을 뿐

- 변수가 아니라 단지 프로퍼티인 y는 delete 연산자로 삭제 가능

var x = 10; //전역 변수 

function foo() {
  //선언하지 않은 식별자에 값을 할당
  y = 20; //window.y =20;
  console.log(x+y);
}

foo(); //30

console.log(window.x); //10
console.log(window.y); //20

delete x; //전역 변수는 삭제되지 않음
delete y; //프로퍼티는 삭제

console.log(window.x); //10
console.log(window.y); //undefined

 

'JavaScript' 카테고리의 다른 글

[Deep dive] 23장 실행 컨텍스트  (0) 2023.08.14
[Deep dive] 22장 this  (0) 2023.08.11
[Deep dive] 20장 strict mode  (0) 2023.08.11
[Deep dive] 19장 프로토타입 (3)  (0) 2023.08.11
[Deep dive] 19장 프로토타입(2)  (0) 2023.08.10