JavaScript #7 – Object-Oriented (객체지향)
Prototype
객체의 원형. 객체는 property를 가질 수 있는 것은 그 동안 계속 봐왔던 사실임. 그 중 prototype이라는 property는 용도가 약속되어 있음.
Prototype에 저장된 속성들은 생성자를 통해서 객체가 만들어질 때 그 객체에 연결됨.
function Ultra(){}
Ultra.prototype.ultraProp = true;
function Super(){}
Super.prototype = new Ultra();
function Sub(){}
Sub.prototype = new Super();
var o = new Sub();
console.log(o.ultraProp);
생성자 Sub를 통해 만들어진 객체 o에서 ultraProp을 찾을 때 실제로는 o, Sub.prototype, Super.prototype, Ultra.prototype에서 ultraProp을 차례로 찾게 됨. 즉, prototype은 객체와 객체를 연결하는 연결고리 역할을 함. 그래서 이러한 관계를 ‘Prototype Chain’ 이라고 함.
Standard Built-in Object (표준 내장 객체)
JavaScript가 기본적으로 가지고 있는 객체. 프로그래밍을 하는데 기본적으로 필요한 도구들.
내장 객체에는 object, function, array, string, Boolean, number, math, date, RegExp가 있음.
var arr = new Array('seoul','new york','ladarkh','pusan', 'Tsukuba');
function getRandomValueFromArray(haystack){
var index = Math.floor(haystack.length*Math.random());
return haystack[index];
}
alert(getRandomValueFromArray(arr));
위 코드는 배열에서 랜덤한 요소 하나를 가지고 오는 코드임. 그런데 저 코드를 array라는 표준내장 객체에 포함시키면, 모든 array가 마치 원래 array 객체의 메소드인 것처럼 위의 기능을 사용할 수 있음.
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');
alert(arr.rand());
Object
Object 객체는 객체의 가장 기본적인 형태를 가지고 있는 객체. 아무것도 상속받지 않는 객체임.
JavaScript의 모든 객체는 Object 객체를 상속받기 때문에 모든 객체는 Object 객체의 Property를 가지고 있음. 또한 Object 객체를 확장해 모든 객체가 접근할 수 있는 API를 만들 수 있음.
Object.prototype.contain = function(neddle) {
for(var name in this){
if(this[name] === neddle){
return true;
}
}
return false;
}
var o = {'name':'BinZIP', 'city':'seoul'}
alert(o.contain('BinZIP'));
var a = ['BinZIP','supernice','bin'];
alert(a.contain('supernice'));
두 번의 alert 모두 True라고 출력되는 것을 확인할 수 있음.
하지만 Object 객체는 확장하지 않는 것이 좋음. 모든 객체에 영향을 주기 때문에 객체가 기본적으로 가지고 있을 것으로 예상하고 있는 객체 외에 다른 객체를 가지고 있는 것은 혼란스러울 수 있기 때문.
for(var name in o){
console.log(name);
}
이런 문제를 회피하기 위해서는 해당 객체의 소속인지 확인할 수 있는 hasOwnProperty를 사용할 수 있음.
for(var name in o){
if(o.hasOwnProperty(name))
document.write(name+'<br/>');
}
Data Type
데이터 타입이란 데이터의 형태를 의미함. 데이터 타입은 크게 객체와 객체가 아닌 것, 이 두 가지로 구분할 수 있음.
객체가 아닌 것에는 숫자, 문자열, Boolean(True/False), null, undefined가 있다. 이런 객체가 아닌 데이터 타입을 Primitive Type(원시 데이터 타입)이라고 함. 그 외 모든 데이터 타입들은 객체임.
그런데 아래 코드를 보자.
var str='hello';
document.write(str.length);
document.write('<br/>');
document.write(str.charAt(0));
문자열에 property와 메소드가 있음. 그렇다면 객체라는 의미인데, 문자열은 객체가 아니라고 했음. 이는 내부적으로는 문자열이 Primitive Type이고 문자열 관련 어떤 작업을 하려고 할 때 JavaScript가 임시로 문자열 객체를 만들어 사용하고, 사용이 끝나면 제거하기 때문임.
문자열이 Primitive Type이지만 이와 관련해 필요한 기능성을 객체지향적으로 제공해야 하는 필요 또한 있기 때문에, Primitive Type을 객체처럼 다룰 수 있도록 제공하는 객체가 있음. 이를 Wrapper Object(레퍼객체)라고 부름. Wrapper Object에는 String, Number, Boolean이 있음.
참조
다음 코드를 보자.
var a = {'id':1};
var b = a;
alert(b.id);
1이라는 것을 당연히 예상할 수 있음. 그렇다면 다음 코드의 결과를 예측해보자.
var a = {'id':1};
var b = a;
b.id=2;
alert(a.id);
결과는 2임. B의 id의 값을 2로 변경했는데 a의 id의 값도 2가 되었음. 이는 변수 b와 a에 담긴 객체가 서로 같음을 의미함.
이는 b에 새로운 객체가 ‘복제’되어 생성되는 것이 아니라, a의 객체를 ‘참조’하고 있다는 의미임.
그런데, 아래 코드를 보자.
var a = 1;
var b = a;
b = 2;
alert(a+' '+b);
여기서는 a의 값이 바뀌지 않았음. 즉, Primitive Type은 복제되어 들어가고, 객체는 참조함을 확인할 수 있음.
그렇다면 함수에 참조 데이터 타입을 넘겨주면 어떻게 될까? 다음 코드를 보자.
var a = {'id':1};
function func(b){
b = {'id':2};
}
func(a);
alert(a.id);
함수 func의 파라미터 b로 전달된 값은 객체 a임. B를 새로운 객체로 대체하는 것은 b가 가지고 있는 객체를 변형하는 것이기 때문에 객체 a에 영향을 주지 않음. 하지만 아래는 다름.
var a = {'id':1};
function func(b){
b.id = 2;
}
func(a);
alert(a.id);
이는 b에 새로운 객체를 만들어 적용하는 것이 아닌 참조된 a에 있는 reference의 속성을 바꾸고 있으므로, 그 속성이 소속된 객체를 대상으로 수정한 것임. 그렇기 때문에, a의 id의 값이 변경됨.
'Programming > Web Programming' 카테고리의 다른 글
[PHP] 카카오톡 자동 응답 봇 구현 (0) | 2018.01.07 |
---|---|
JavaScript Basic #6 (0) | 2017.07.21 |
JavaScript Basic #5 (0) | 2017.07.18 |
JavaScript Basic #4 (0) | 2017.07.18 |
JavaScript Basic #3 (0) | 2017.07.16 |