Javascript가 기본적으로 제공하는 객체
자바스크립트나 호스트 환경이 자바스크립트 개발자에게 제공하는 미리 만들어진 객체이다.
사용자 정의 객체(표준 내장 객체와 대비)
사용자가 직접 객체를 만들고 객체 안에 속성이나 함수를 정의해서 사용하는 객체
Array.prototype.random = function() {
let index = Math.floor(this.length * Math.random());
return this[index];
}
const arr = new Array('sung', 'jae', 'brian', 'pil', 'don');
console.log(arr.random());
자바스크립트가 제공하는 내장객체에 사용자가 필요에 따라서 메소드를 추가하는 하이브리드형은 장점이 있으며, 프로토타입이라는 기능을 사용한다.
프로토타입을 확장하는 것을 통해서 모든 배열(객체)이 공통적으로 가지고 있어야 되는 api를 사용자가 직접 정의할 수 있다.
공통적으로 사용해야 하는 로직이 있는 경우 프로토타입을 이용해 내장 객체를 확장할 수 있다.
Object 객체는 객체의 가장 기본적인 형태를 가지고 있는 객체로 아무것도 상속받지 않은 최상위 객체이다.
Object는 Javascript의 모든 객체의 부모로서(공통적인 조상) 모든 객체는 Object 객체를 상속 받아 Object 객체의 프로퍼티를 가지고 있다.
<Object API 종류>
1) Object.____(변수) : 하위 객체는 사용 불가
Object는 생성자 함수를 의미하며 프로퍼티를 갖고 있다.
Object.keys(arr) 형태로 사용
2) Object.prototype.____() : 모든 객체들이 활용 가능
객체를 만들고 그 객체를 담고있는 '변수.메소드(id.toString()) 형태'로 사용
모든 객체들은 .prototype이라는 메소드를 가지고 있으며, 프로토타입에 프로퍼티나 메소드를 상속받는다.
생성자 함수(new Object())를 이용해서 객체를 생성하면 객체는 생성자의 프로토타입의 프로퍼티에 저장되어 있는 객체를 원형으로 하는 객체가 생성되는 것을 프로토타입 소속이라 한다.
즉, 객체를 생성하고 그 객체에 대한 메소드로서 사용을 하게 된다.
Object 객체를 확장하면 모든 객체가 접근할 수 있는 API를 만들 수 있다.
그러나 Object 객체를 확장하면 모든 객체에 영향을 주기 때문에 위험 가능성이 있다.
데이터 형태를 의미하며 데이터 타입은 객체와 객체가 아닌 것으로 구분할 수 있다.
객체가 아닌 데이터 타입을 원시 데이터 타입(primitive type)이라고 한다.
아래는 원시 데이터 타입이며, 이 외의 모든 데이터 타입들은 객체이다.
문자열은 프로퍼티와 메소드가 있어 객체라고 할 수 있는데 위의 내용과 모순된다.
문자열이 객체가 아니라고 하는 이유는 '내부적으로' 문자열이 원시 데이터 타입이고 문자열과 관련된 작업을 할 때 자바스크립트는 '임시로 문자열 객체를 만들고 사용이 끝나면 제거'하기 때문이다.
원시 데이터 타입과 객체는 다른 동작 방법을 가지고 있어 '분별' 할 수 있어야 한다.
const str = 'hello';
str.prop = 'everybody';
console.log(str.prop); // undefined
str.prop 하는 순간 자바스크립트는 내부적으로 String 객체가 만들어진다.
prop 프로퍼티는 이 객체에 저장되고 곧 제거되기 때문에 prop라는 속성이 저장된 객체는 존재하지 않는다.
원시 데이터형을 객체처럼 다룰 수 있도록 하기 위한 객체를 레퍼객체(wrapper object)라고 하며 자바스크립트는 이를 제공한다.
레퍼객체는 String, Number, Boolean이 있고 null, undefined는 존재하지 않는다.
a = 1; // 숫자(원시 데이터형)
a = {'id': 1}; // 객체(참조 데이터형/참조 자료형)
변수에 담겨있는 데이터가 원시형이면 그 안에는 '실제 데이터'가 들어있고,
객체이면 변수 안에는 '데이터에 대한 참조 방법'이 들어있다고 생각하자.
복사와 비교하면 참조는 저장 장치의 용량을 절약할 수 있고, 원본 파일을 사용하고 있는 모든 복제본이 동일한 내용을 유지할 수 있다.
// 참조 데이터 타입을 인자로 넘겼을 때
let a = {'id': 1};
function func(b) {
b = {'id': 2};
}
func(a);
console.log(a.id); // 1
함수 func의 파라미터 b로 전달된 값은 객체 a이다. (b = a)
b를 새로운 객체로 대체하는 것은 (b = {'id': 2}) 'b가 가리키는 객체'를 변경하는 것이기 때문에 객체 a에 영향을 주지 않는다.
let a = {'id': 1};
function func(b) {
b.id = 2;
}
func(a);
console.log(a.id); // 2
파라미터 b는 객체 a의 레퍼런스로 이 값의 속성을 바꾸면 그 '속성이 소속된 객체'도 바뀌기 때문에 b의 변경은 객체 a도 변경되어 영향을 미친다.