표준 내장 객체(Standard Built-in Object)는 자바스크립트 기본 객체들.
내장 객체가 중요한 이유는 프로그래밍을 하는데 기본적으로 필요한 도구들이기 때문에.
자바스크립트는 아래와 같은 내장 객체를 가지고 있다.
var arr = new Array('seoul','new york','ladarkh','pusan', 'Tsukuba');
function getRandomValueFromArray(haystack){
var index = Math.floor(haystack.length*Math.random());
return haystack[index];
}
console.log(getRandomValueFromArray(arr));
배열에 대해서
floor는 (바닥) 뒤의 소수점을 제거하는 역할.
length는 길이를 구하는 역할.
random은 0부터 1사이의 소수를 가져옴.
즉. index에 들어가는 값은 실행될때마다 랜덤하게 값을 가져온다.
위의 예제를 개선하려면 함수를 배열 객체에 포함시키는 것이다.
Array.prototype.rand = function(){
var index = Math.floor(this.length*Math.random());
return this[index];
}
var arr = new Array('seoul','new york','ladarkh','pusan', 'Tsukuba');
console.log(arr.rand());
배열의 프로토타입에 접근, 함수를 포함시킨다.
동시에 자바스크립트의 모든 객체는 Object 객체를 상속 받는데, 그런 이유로 모든 객체는 Object 객체의 프로퍼티를 가지고 있다.
object.keys는 배열의 키값만을 반환하는 역할을 한다.
요렇게 이름이 아니라 name age 등의 키값만을 가져온다.
또한 Object 객체를 확장하면 모든 객체가 접근할 수 있는 API를 만들 수 있다. 아래는 Object 객체를 확장한 사례다.
Object.prototype.contain = function(neddle) {
for(var name in this){
if(this[name] === neddle){
return true;
}
}
return false;
}
var o = {'name':'egoing', 'city':'seoul'}
console.log(o.contain('egoing'));
var a = ['egoing','leezche','grapittie'];
console.log(a.contain('leezche'));
Object 객체는 확장하지 않는 것이 바람직하다. 왜냐하면 모든 객체에 영향을 주기 때문이다.
for(var name in o){
console.log(name);
}
결과는 name contain
확장한 프로퍼티인 contain이 포함되어 있다. 객체가 기본적으로 가지고 있을 것으로 예상하고 있는 객체 외에 다른 객체를 가지고 있는 것은 개발자들에게 혼란을 준다. 이 문제를 회피하기 위해서는 프로퍼티의 해당 객체의 소속인지를 체크해볼 수 있는 hasOwnProperty를 사용하면 된다.
for(var name in o){
if(o.hasOwnProperty(name))
console.log(name);
}
hasOwnProperty는 인자로 전달된 속성의 이름이 객체의 속성인지 여부를 판단한다. 만약 prototype으로 상속 받은 객체라면 false가 된다.
원시 데이터타입 vs 객체 데이터 타입.
var str = 'coding';
console.log(str.length); // 6
console.log(str.charAt(0)); // "C"
문자열은 분명히 프로퍼티와 메소드가 있다. 그렇다면 객체다. 그런데 왜 문자열이 객체가 아니라고 할까? 그것은 내부적으로 문자열이 원시 데이터 타입이고 문자열과 관련된 어떤 작업을 하려고 할 때 자바스크립트는 임시로 문자열 객체를 만들고 사용이 끝나면 제거하기 때문이다. 이러한 처리는 내부적으로 일어난다. 그렇기 때문에 몰라도 된다. 하지만 원시 데이터 타입과 객체는 좀 다른 동작 방법을 가지고 있기 때문에 이들을 분별하는 것은 결국엔 필요하다.
var str = 'coding';
str.prop = 'everybody';
console.log(str.prop); // undefined
str.prop를 하는 순간에 자바스크립트 내부적으로 String 객체가 만들어진다. prop 프로퍼티는 이 객체에 저장되고 이 객체는 곧 제거 된다. 그렇기 때문에 prop라는 속성이 저장된 객체는 존재하지 않게된다. 이러한 특징은 일반적인 객체의 동작 방법과는 다르다.
하지만 문자열과 관련해서 필요한 기능성을 객체지향적으로 제공해야 하는 필요 또한 있기 때문에 원시 데이터 형을 객체처럼 다룰 수 있도록 하기 위한 객체를 자바스크립트는 제공하고 있는데 그것이 레퍼객체(wrapper object)다.
레퍼객체로는 String, Number, Boolean이 있다. null과 undefined는 레퍼 객체가 존재하지 않는다.
var a = 1;
var b = a;
b = 2;
console.log(a); // 1
변수b에 변수 a의 값이 복제 된 것이다.
var a = {'id':1};
var b = a;
b.id = 2;
console.log(a.id); // 2
변수 b 객체의 id 값을 2로 변경--- a.id의 값도 2가 된다. 변수 b, a에 담긴 객체가 서로 같다.
참조(reference)
원본을 복제한 것이 아니라 원본 파일을 참조(reference)하고 있는 것
var a = 1;
function func(b){
b = 2;
}
func(a);
console.log(a);
결과는 1
그럼 참조 데이터 타입을 인자로 넘기면??
var a = {'id':1};
function func(b){
b = {'id':2};
}
func(a);
console.log(a.id); // 1
결과는 1이다.
함수 func의 파라미터 b로 전달된 값은 객체 a이다.
(b = a) b를 새로운 객체로 대체하는 것은 (b = {'id':2})
b가 가르키는 객체를 변경하는 것이기 때문에 객체 a에 영향을 주지 않는다.
하지만 아래는 다르다.
var a = {'id':1};
function func(b){
b.id = 2;
}
func(a);
console.log(a.id); // 2
파라미터 b는 객체 a의 레퍼런스다. 이 값의 속성을 바꾸면 그 속성이 소속된 객체를 대상으로 수정작업을 한 것이 되기 때문에 b의 변경은 a에도 영향을 미치게 된다.