반응형
생성자 함수를 이용한 객체 생성
[광고 누르면 오늘의 행운 상승!!]
-
객체 생성 방법 : new 연산자, 생성자 이용
-
JavaScript는 클래스 존재 x
→ new 연산자를 이용한 객체는 class의 instance 아님! -
JavaScript는 객체지향 프로그래밍 언어이고 Class를 흉내내어 생성자 함수를 작성할 수 있음.
생성자 함수와 Prototype
-
This 키워드
this 키워드는 method에서 사용되며 method를 호출한 호출 객체를 가리킴 -
전역 영역에 생성이 되는 프로퍼티와 메소드는 window 객체의 프로퍼티와 메소드가 된다.
→ this.xxx를 하면 window 객체를 가리킨다. -
일반적인 함수에서 함수 내부에 있는 변수나 함수는 객체의 properyt나 method가 아님
var varA = "global"
function testFunc(){
this.varA = "local";
this.varB = "string";
this.makeString = function(){
document.write(this.varA + " " + this.varB);
};
makeString();
}
testFunc();
this는 호출 객체를 의미함
this.varA는 전역변수인 varA를 변경하게 됨
전역변수 varA 는 "global"에서 "local"로 변경됨.
- new 연산자를 이용한 생성자 함수
var varA = "global"
function testFunc(){
this.varA = "local";
this.varB = "string";
this.makeString = function(){
document.write(this.varA + " " + this.varB);
};
makeString();
}
var myObj = new testFunc();
myObj.makeString();
new 연산자와 함께 사용하면 생성자 함수가 됨
new 연산자가 새로운 빈 객체를 만들 때 : this가 가르킴
this는 새로 생성되는 객체의 이름을 가리킴
myObj 객체를 의미함.
생성자 함수
- 생성할 객체에 있는 property와 그 property는 어떻게 초기화 될 것인지 정의해 놓은 함수
- 객체지향 프로그래밍 언어의 class와 흡사함
- 생성자 함수는 'class'또는 '모조 class'라고 부름
var myCircle = new circle([5,15], 10);
circle 생성자 함수를 new 연산자를 적용하여 새로운 객체를 생성함
myCircle이라는 빈 객체를 생성한 후 this를 myCircle객체를 가리키게 함
-> Circle 함수를 호출하여 전달인자를 이용하여
빈 객체의 property와 method를 생성하고 초기화함
생성자 함수는 객체를 생성하기 위해 작성되기 때문에 내부에 return 반환 값이 없다.
Prototype
-
모든 함수에는 Prototype라는 property가 있음
→ 함수를 정의할 때 자동으로 생성되는 property임
→ 하나의 constructor property를 가지고 있음 -
모든 객체에서 동일한 property를 가지고 있다면 메모리 낭비가 된다.
<<Prototype test>>
function Member(id,name){
this.id = id;
this.name = name;
}
Member.prototype.insa = function(){
console.log(this.name + "하이");
}
var m1 = new Member("a", "a님");
var m2 = new Member("b", "b님");
console.dir(m1);
m1.insa();
console.dir(m2);
m2.insa();
//console.dir(Member)
//var m = {};
//console.dir(m);
//JavaScript는 자동으로 prototype을 생성함
//prototype property는 객체를 값으로 가지고 있고 이 객체는
//constructor라는 property를 가지고 있음
//constructor property는 생성자 함수로 객체가 생성되었을 때 자신의 생성자 함수를 알려줌
객체마다 중복되는 변하지않는 property나 method를 prototype으로 작성하여
메모리를 절약할 수 있음
property 가리기
- 생성된 객체의 property를 읽으려고 할 때 먼저 자신의 property를 검사함
- 객체 자신의 property에 읽으려고 하는 property가 없을 시 prototype 객체에 읽으려는 property가 있는지 검사함. → 있다면 실행한다.
myCircle.area = function(){
return "myCircle AREA";
}
document.write(myCircle.area());
myCircle객체에 area method를 추가하였음
-> myCircle 객체는 두 개의 area method를 가지게 됨
myCircle.area()로 area method에 접근하려 할 때 먼저
myCircle 객체를 검사하여 area method가 있으면 바로 실행하고 prototype객체는 검사를 하지 않음
-> prototype 객체에 있는 area는 접근할 수 없음
※ 객체 property가 prototype 객체의 property를 가림 ※
instance property
var myCircle = new Circle([0,0] , 10);
var yourCircle = new Circle([10,10] , 5);
- 동일한 참조임
- 만일 Circle.prototype.area의 함수값을 변경하면
- 그 영향은 myCircle.area()와 yourCircle.area()에 동일하게 적용됨
class property
var pi = Math.Pi
- JavaScript에 원주율을 구하기 위해 Math.PI를 이용함
- JavaScript의 생성자 property객체를 class 라고 부른다면 property Pi는 class property임
- 원주율과 같이 Math로 생성된 객체의 속성이 아니라 Math 자체의 속성을 표현하기
위해 Class property를 사용함
원주율이 Class property가 아니라면
var mathObject = new Math();
var pi = math.Object.Pi;
class method를 JavaScript를 구현하기 위해서는
- this를 사용하지 않는 method를 정의하면 됨
- this는 new 연산자에 의해 생성자 함수로 인해 생성된 객체를 가리킴
- class 메소드는 객체를 생성하지 않기 때문에 this를 생성하지 않음
비공개 property
- 객체 내부의 메서드만 접근이 가능하고 외부 코드에서는 조작할 수 없는 property
- BUT - JavaScript는 비공개 property에 대한 별도의 문법이 없음
→ 외부 코드가 수정되면 프로그래밍 전반에 걸쳐 문제가 될 수 있음
비공개 멤버
- 비공개 property를 만드는 문법이 있는 새로운 JavaScript를 기대할 수 없지만 비공개 property는 분명히 필요함
- 지역변수와 클로저를 이용하면 비공개 property를 구현할 수 있음
function PrivateJs(){
var privateProperty = 'private Property';
this.openProperty = 'Open Property';
this.getPrivate = function(){
return privateProperty;
};
}
- 코드에서 privateProperty 생성자 함수의 지역 변수로 객체의 property로서의 역할을 함
- 지역 변수이기 때문에 외부에서 property로 접근이 불가능함
- 객체의 property인 OpenProperty는 외부 코드에서 접근할 수 있음
- this.getPrivate를 이용하여 privateProperty 접근 가능
비공개 멤버의 문제점
- setPrivate 특권 method를 작성하여 비공개 property를 수정할 수 있게 만들 수 있음
→ privateProperty property는 더 이상 비공개 property가 아님
→ 외부 코드에서 비공개 property를 수정할 수 있는 방법을 만들어서는 안됨
→ BUT 클로저를 이용한 비공개 멤버는 외부 코드에서 수정되는 특별한 경우가 존재하는 버그가 있음
※ 값이 배열이나 객체일 경우 참조로 전달되기 때문에 비공개 property를 변경할 수 있게 됨 ※
function PrivateJs(){
var privateProperty = ['melon', 'orange', 'apple'];
this.openProperty = 'Open Property';
this.getPrivate = function(){
var copiedProperty = [];
for (var i = 0; i < privateProperty.length; i++){
copiedProperty.push(privateProperty[i]);
}
return copiedProperty;
};
}
- getPrivate method가 비공개 property인 priavteProperty배열을 복사하여 전달하기 때문에
비공개 property는 외부 코드에서 변경할 수 없게 됨
공통객체 메소드
- toString(), valueOf()
- 공통으로 가지게 된 이유
- 모든 객체가 생성될 때 Object class의 method를 상속받기 때문
- class를 설계하여 객체를 생성할 때도 이 공통 객체 method는 상속됨
- 공통 객체 method는 기대하는 결과를 반환하지 못하는 경우
→ 공통 객체 method를 재 작성 하면 됨
→ 재 작성 된 method는 상속 받은 method를 가리게 됨
toString
- 객체를 문자열로 표현함 -circle을 예로 들면 원의 원점과 반지름 넓이 등을 문자열로 반환
→ 상속받은 toString()은 객체라는 표시만 반환됨
→ 재 정의하여 사용해야 한다.
Cicle.prototype.toString = function(){
return "원점이 ("+ this.originX + " , " this.originY + ")이며 반지름이 "
this.raduis +" 인 원입니다.]";
}
var myCircle = new Circle([0,0], 10);
valueOf
- 문자열 이외의 기본 데이터 타입으로 변환을 위해 사용됨
객체를 숫자로 나누려고 할 때 객체는 숫자로 자동 변환되려고 노력함
document.write(myCircle / 2);
결과는 myCircle 객체가 숫자로 변환되지 않아서 NaN이 출력됨
Circle.prototype.valueOf = function(){
return this.area();
}
document.write(myCircle / 2);
숫자 출력
반응형
'5. 웹 프로그래밍 > 3. JavaScript' 카테고리의 다른 글
Class 상속 [JavaScript][mixIn][prototype 상속] (0) | 2020.03.19 |
---|---|
객체의 이해 [JavaScript][객체][NameSpace] (0) | 2020.03.19 |
함수의 유효 범위 [JavaScript][클로저][apply/call] (0) | 2020.03.19 |
Function2 [JavaScript][생성자함수정의][익명함수] (0) | 2020.03.19 |
이벤트의 이해 [JavaScript][이벤트전파][이벤트막기] (0) | 2020.03.19 |