빌트인 객체 ? 멋사 수업을 듣기 전이었다면 익숙하지 않은 단어에 몸서리 쳤을 수도 ~ 있지만 !
멋사 수업을 듣는 중인 나는 다르다 ! 많이 익숙한 단어가 나와서 반가울 정도 ~
그럼 빌트인 객체 정리 가보자고 !
자바스크립트는 Object
, Stirng
, Date
, RegExp
, Map/Set
, Relfect
, JSON
, Error
등 40여개의 표준 빌트인 객체를 제공한다. 빌트인 객체를 생성자 함수 객체 여부에 따라 구분을 해보자.
생성자 함수 객체
: Math, Reflect, JSON을 제외한 모든 표준 빌트인 객체생성자 함수 객체
&& 표준 빌트인 객체
: 프로토타입 메서드, 정적 메서드를 제공생성자 함수 객체
가 아닌 표준 빌트인 객체
: 정적 메서드만 제공prototype
프로퍼티에 바인딩된 객체 = 인스턴스의 프로토타입생성자 함수인 표준 빌트인 객체가 생성한 인스턴스의 프로토타입
은, 표준 빌트인 객체의 prototype
프로퍼티에 바인딩된 객체다. 예를 들면, Obejct 생성자 함수를 호출하여 생성한 Obejct 인스턴스
의 프로토타입은 Obejct.prototype
이다.
표준 빌트인 객체의 prototype 프로퍼티에 바인딩된 객체(Object.prototype)는 다양한 기능의 빌트인 프로토타입 메서드를 제공한다. 프로토타입 메서드는, 모든 인스턴스가 상속을 통해 사용 가능하다.
인스턴스 없이 정적으로 호출이 가능한 정적 메서드(static method)를 제공하기도 한다.
const numObj = new Number(1.5); // Number {1.5}
console.log(numObj.toFixed()); // 프로퍼티 메서드
console.log(Number.isInteger(0,5)); // 정적 메서드
numObj
가 Number.porototype
를 상속받았기 때문에 Number.porototype의 빌트인 메서드를 사용 가능toFixed
: 인스턴스(Number.porototype)없이 사용 가능한 정적 메서드원시값에는 왜 표준 빌트인 생성자 함수가 존재할까?
원시값은 객체가 아니므로, 프로퍼티나 메서드를 가질 수 없는데도 불구하고 ! 마치 객체처럼 동작한다.
const str = 'h';
console.log(str.length); // 5
console.log(str.toUpperCase()); // H
(wrapper object)
원시값
에 대해 마치 객체처럼 마침표 표기법으로 접근하면 아래의 과정이 연달아 발생한다.
래퍼 객체
로 변환래퍼 객체
로 변환된 원시값은 프로퍼티/메서드를 접근/호출예를 들어, 문자열에 마침표 표기법으로 접근하면 래퍼 객체인 String 생성자 함수의 인스턴스가 생성되고, 문자열은 래퍼 객체의 [[StringData]]
내부 슬롯에 할당된다.
이때 문자열 래퍼 객체인 String
생성자 함수의 인스턴스는 Stirng.prototype
메서드를 상속받아 사용할 수 있다.
null
, undefined
따라서 null과 undefined를 객체처럼 사용하면 에러가 발생한다.
(+) Symbol 역시 생성자 함수가 아니기 때문에 사용할 수 없다.
전역 객체
코드가 실행되기 이전 단계에 자스 엔진에 의해 어떤 객체보다도 먼저 생성되는 특수한 객체전역 객체는 어떤 객체에도 속하지 않는 최상위 객체이다.
브라우저 환경에서는 window
, Node.js 환경에서는 global
이 전역 객체를 가리키고
두 환경에서 모두 사용이 가능한 globalThis
라는 식별자도 ES11에서 등장했다.
전역 객체
는 표준 빌트인 객체, 호스트 객체(Web API), var 키워드로 선언한 전역 변수, 전역 함수를 프로퍼티로 갖는다. 즉 계층적 구조상 어떤 객체에도 속하지 않은 모든 빌트인 객체의 최상위 객체다.
하지만 프로토타입 상속 관계상 최상위 객체라는 의미는 아니고, 전역 객체
는 어떤 객체의 프로퍼티도 아님을 의미한다.
Infinity
무한대를 나타내는 숫자값 Infinity를 가짐NaN
숫자가 아님(Not a Number)을 나타내는 숫자값 NaNundefined
원시 타입 undefined를 값으로 가짐eval
eval
함수는 자스 코드를 나타내는 문자열을 인수로 전달 받는다.
/*
* 주어진 문자열 코드를 런타임에 평가/실행
* @param {string} code - 코드를 나타내는 문자열
* @returns {*} - 문자열 코드를 평가/실행한 결과값
*/
eval(code)
전달 받은 문자열 코드가 표현식이라면, 문자열 코드를 런타임에 평가하여 값을 생성하고,
전달 받은 문자열 코드가 문이라면, 문자열 코드를 런타임에 실행한다.
문자열 코드가 여러 개의 문으로 이루어져있다면, 모든 문을 실행한다.
eval('1 + 2'); // 3
eval('var x = 5') // undeifned
console.log(x) // 5
eval
함수는 기존의 스코프를 런타임에 동적으로 수정한다.
eval
함수를 통해 사용자로부터 입력받은 콘텐츠를 실행하는 것은 보안에 매우 취약하다.
또한 eval
함수를 통해 실행되는 코드는 최적화가 진행되지 않아 처리 속도도 느리다.
따라서 eval
함수는 사용하지 말자!
inFinite
전달받은 인수가 정상적인 유한수인지 검사한다.
/*
* 전달받은 인수가 유한수인지 확인하고 그 결과를 반환
* @param {number} testValue - 검사 대상 값
* @returns {boolean} 유한수 여부 확인 결과
*/
inFinite(testValue)
유한수면 true, 무한수이면 false를 반환한다. 이때 전달받은 인수가 숫자 타입이 아니라면 형 변환 후 검사를 수행한다. NaN으로 평가되는 값은 false를 반환한다.
inFinite(0) // true
inFinite('10') // true
inFinite(null) // true
inFinite(Infinity) // false
inFinite(NaN) // false
inFinite('hi') // false
inNaN
전달받은 인수가 NaN인지 검사하여 불린값을 반환한다. 전달받은 인수가 숫자가 아니라면 형변환 후 검사를 수행한다.
/*
* 전달받은 인수가 NaN인지 확인하고 그 결과를 반환
* @param {number} testValue - 검사 대상 값
* @returns {boolean} NaN 여부 확인 결과
*/
inNaN(testValue)
isNaN(NaN) // true
isNaN(10) // false
isNaN('hi') // true
isNaN('10') // false
isNaN('10.12') // false
isNaN('') // false
isNaN(' ') // false
isNaN(true) // false
isNaN(null) // false
isNaN(undefined) // true
isNaN({}) // true
isNaN(new Date()) // false
isNaN(new Date().toString()) // true
parseFloat
/*
* 전달받은 문자열 인수를 실수(부동 소수점 숫자)로 해석하여 반환
* @param {string} string - 변환 대상 값
* @returns {number} 변환 결과
*/
parseFloat(string)
parseFloat('3.14') // 3.14
parseFloat('10.00') // 10
parseFloat('34 54 64') // 34
parseFloat('40 years') // 40
parseFloat('he was 40') // NaN
parseFloat(' 60 ') // 60
parseInt
/*
* 전달받은 문자열 인수를 실수(부동 소수점 숫자)로 해석하여 반환
* @param {string} string - 변환 대상 값
* @returns {number} 변환 결과
*/
parseFloat(string)
parseFloat('3.14') // 3.14
parseFloat('10.00') // 10
parseFloat('34 54 64') // 34
parseFloat('40 years') // 40
parseFloat('he was 40') // NaN
parseFloat(' 60 ') // 60
isFinite
전달받은 인수가 정상적인 유한수인지 검사한다.
isFinite(0) // true
isFinite('10') // true
isFinite(null) // true (0)
isFinite(Infinity) // false
isFinite('hi') // false
isNaN
전달받은 인수가 NaN인지 검사한다.
isNaN(NaN) // true
isNaN(undefined) // true
isNaN(10) // false
isNaN('hi') // true
isNaN('10') // false (10)
isNaN('') // false (0)
isNaN(' ') // false (0)
isNaN({}) // true
parseFloat
전달받은 문자열 인수를 실수(소수점 숫자)로 해석한다.
parseFloat('3.14') // 3.14
parseFloat('30 50 50') // 30
parseFloat('hi i am 10') // NaN
parseInt
전달받은 문자열 인수를 정수로 해석한다.
parseInt('10') // 10
parseInt('10', 2) // 2진수로 계산
parseInt('10', 8) // 8진수로 계산
parseInt('10', 16) // 16진수로 계산
parseInt('50 60 60') // 50
parseInt('hi im 70') // NaN
encodeURI, decodeURI
encodeURI
: 완전한 URI를 문자열로 전달받아 이스케이프 처리를 위해 인코딩 (한글 > 컴퓨터 언어)decodeURI
: 인코딩된 URI를 인수로 전달받아 이스케이프 처리 이전으로 디코딩 (컴퓨터 언어 > 한글)URI 인터넷에 있는 자원을 나타내는 유일한 주소, 하위개념으로 URL, URN이 있음
- URL : Protocol, Domain, Port, Path
- URN : Query, Fragment
인코딩
이란 URI의 문자들을 이스케이프 처리하는 것을 의미한다.
이스케이프
처리란, 네트워크를 통해 정보를 공유할 때 어떤 시스템에서도 읽을 수 있는 아스키 문자 셋으로 변환하는 것을 의미한다. 한글을 포함한 대부분의 외국어 등은 이스케이프 처리가 필요하다.
encodeURIComponent, decodeURIComponent
encodeURIComponent
: encodeURI
와 같지만 =, ?, &까지 인코딩decodeURIComponent
: decodeURI
와 같지만 =, ?, &까지 디코딩var x = 10;
function foo(){ y = 20; } // window.y = 20
console.log(x + y); // 30
foo 함수 내부의 y는 선언하지 않은 식별자이다. 하지만 참조에러가 발생하지 않고 전역 변수처럼 동작했다.
선언하지 않은 식별자에 값을 할당하면, 전역 객체의 프로퍼티가 되기 때문이다.
이러한 현상을 암묵적 전역
이라고 한다.
전역 변수처럼 동작하긴 했지만, 사실 y는 단지 전역 객체의 프로퍼티로 추가된 것이다.
따라서 y는 호이스팅이 발생하지 않기 때문에 foo 함수 실행 전에는 참조 에러
가 발생한다.
또한 프로퍼티이기 때문에 delete
연산자로 삭제가 가능하다.
멋사 수업 내용이 많이 어려워지고 있다 ! 하지만 잘 소화했죠? 꽤 멋지죠?
그래서 모던 자스에 시간을 많이 못쓰지만 .. 그래도 짬짬히 읽으러 와야겠다 !
며칠 전에는 프로토타입을 다시 읽어봤다. 수업을 듣고, 자바스크립트 코어를 다시 읽고, 나름의 열띤 토론도 했다. 그 후에 프로토타입을 다시 읽으니까 ... 이제야 퍼즐이 맞춰졌다.
확실히 모던 자스가 정말 도움이 된다 !
앞으로도 화이팅 가보자고~