반응형

생성자 함수를 이용한 객체 생성

[광고 누르면 오늘의 행운 상승!!]

  • 객체 생성 방법 : 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()
  • 공통으로 가지게 된 이유
  1. 모든 객체가 생성될 때 Object class의 method를 상속받기 때문
  2. 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);

숫자 출력
반응형

+ Recent posts