객체(Object)란 ?

- 객체는 JavaScript 언어만이 가지고 있는 특징을 기초로 이루는 자료형으로, 데이터를 저장하고 있는 프로퍼티(property) 및 프로퍼티에 저장된 데이터에 조작을 가할 수 있는 method의 집합으로 구성된다.

- 객체는 '이름(key) : 값(value)' 형태의 프로퍼티들을 저장하는 컨테이너이다. 기본 타입은 하나의 값만을 가지지만 참조 타입인 객체는 여러 개의 프로퍼ㅣ들을 포함할 수 있으며, 이러한 객체의 프로퍼티들은 기본 타입의 값을 포함하거나 다른 객체를 가리킬 수 있다. 

- null 과 undefined 를 제외한 모든 원시 타입도 객체로 취급된다. 이러한 원시 타입들에도 프로퍼티가 추가될 수 있고, 모두 객체로서의 특징을 갖는다. (숫자, 문자열, 배열, 함수, 정규 표현식 등)

- 객체를 사용할 때는 속성 (property) 이름을 이용해서 속성 값을 읽거나 쓸 수 있다.

- 자바스크립트에선, 실행 시점에 특정 객체에 속성을 추가하거나 제거할 수 있다.

 

프로토타입(prototype) 기반 언어

- 자바스크립트는 클래스 기반이 아닌 프로토타입(prototype)을 기반으로 하는 객체 기반 언어이다.

- 프로토타입 기반 언어는 프로토타입 객체라는 개념이 있으며, 새로운 객체의 초기 속성을 가져오는 템플릿(template)으로 사용되는 객체이다. 객체 원형인 프로토타입을 이용하여 새로운 객체를 만들며, 생성된 객체는 또 다른 객체의 원혀이 될 수 있다.

- 프로토타입 언어는 클래스 없이(Class-less)객체를 생성할 수 있다. ECMAScript 6에서 클래스가 추가 되었다.

- 모든 객체는 객체를 만들거나 런타임에 고유한 속성을 지정할 수 있다.

- 모든 객체를 다른 객체의 프로토타입으로 연결하여 두 번째 객체가 첫 번째 객체의 속성을 공유할 수 있다.

- 프로토 타입 객체를 참조하는 prototype 속성과 객체 멤버인 _proto_ 속성이 참조하는 숨은 링크가 있다.

_proto_ : 상위에서 물려 받은 객체의 프로토타입에 대한 정보(prototype link)

prototype : 자신의 프로토타입 객체로, 하위로 물려줄 프로토 타입의 정보(prototype object)

 

특징

- 모든 객체는 다른 객체로부터 상속을 받는다.

- 생성자 함수를 이용하여 객체 세트를 정의하고 생성할 수 있다.

- class와 마찬가지로 new 연산자로 하나의 객체(인스턴스)를 생성할 수 있다. 

- 하나의 객체를 생성자 함수와 결합된 프로토타입에 할당함으로써 객체의 계층구조를 생성한다.

- 프로토타입 체인에 따라 속성을 상속받는다.

- 생성자 함수 혹은 포로토타입은 초기 속성들을 명시한다. 개별 객체 혹은 전체 객체 세트에 동적으로 속성을 추가, 삭제할 수 있다.

 

 

객체생성 - 객체 리터널을 이용한 객체 생성

더보기

객체 리터널(이니셜라이저)를 이용한 객체 생성

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">

<script type="text/javascript">
// 객체 리터널(이니셜라이저)를 이용한 객체 생성
var obj = {name:'홍길동', age:20}; // 프로퍼티이름:값, 프로퍼티명은 문자열만 가능
// var obj = {'name':'홍길동', 'age':20}; // 가능

console.log( typeof obj ); // "object"
console.log( obj );
console.dir( obj );

// 객체 속성 값 확인
console.log( obj.name ); // 홍길동

// 객체 속성 값 변경
obj.name = '김자바';
console.log( obj.name ); // 김자바

var s;
s = obj.age >= 19 ? obj.name +"님은 성인 입니다." : obj.name+"님은 성인이 아닙니다.";
console.log( s );

obj.Age = 22; // 대소문자가 다르면 에러가 나오지 않고 새로운 속성이 추가된다.
console.log( obj.age ); // 20

console.dir( obj );

// 객체 리터널(이니셜라이저)를 이용한 객체 생성 - 2
var obj2 = { }; // 빈 객체
console.log( typeof obj2 ); // object

// 실행시 동적으로 속성 추가
obj2.subject = "자바";
console.log( obj2 );
console.log( obj2.subject );

// 객체 리터널(이니셜라이저)를 이용한 객체 생성 - 3
var obj3 = {
	name : '홍길동',
	age : 20,
	state : function() {
		return this.age >= 19 ? '성인' : '미성년자'; // this 생략불가
	},
	msg : function() {
		var s = `${this.name}님은 ${this.state()} 입니다.`; // 템플릿 리터널
		console.log(s);
	}
};

console.log( obj3 );
obj3.msg();

</script>

</head>
<body>

<h3>객체 만들기</h3>

</body>
</html>

 

객체 이니셜라이저(object initializer) 를 이용한 객체 생성

- 객체 이니셜라이저를 이용하여 객체를 생성할 수 있으며, 리터럴 표기에 의한 객체(literal notation, 객체 리터널) 생성이라고도 한다.

- 객체 이니셜라이저는 여러 가지 프로퍼티를 가진 객체를 쉽게 정의할 수 있도록 디자인된 표기법이다.

- 중괄호 { } 를 이용해서 객체를 생성하며, 중괄호 { } 안에 아무것도 적지 않은 경우는 빈 객체가 된다.

- 중괄호 { } 안에 '프로퍼티 이름:프로퍼티 값' 형태로 표기하면, 해당 프로퍼티가 추가된 객체를 생성할 수 있다.

- 객체의 프로퍼티들이 객체의 특징을 규정한다. 

 

 

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

더보기
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<script type="text/javascript">
// 생성자 함수를 이용한 객체 생성

// 생성자 함수 작성 - 생성자는 대문자로 시작한다.
function User(name, age) {
	this.name = name;
	this.age = age;
	
	this.state = function() {
		return this.age >= 19 ? "성인":"미성년자";
	}
	
	this.msg = function() {
		var s = this.name + "님은 " +this.state()+"입니다.";
		console.log(s);
	}
}
// 생성자 함수를 이용한 객체 생성
var obj = new User('홍길동', 20);
console.log(obj.name);
obj.msg();

// Object.create()메소드를 이용한 객체 생성
var Book = {
	subject:'자바',
	msg: function() {
		return '좋아하는 과목은 '+this.subject+'입니다.';
	}
};

var b1 = Object.create(Book);
var b2 = Object.create(Book);
b1.subject = 'HTML';
b2.subject = 'CSS';

console.log(Book.msg());
console.log(b1.msg());
console.log(b2.msg());


</script>
</head>
<body>

<h3>객체 생성</h3>

</body>
</html>

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

- 객체 타입을 정의하는 생성자 함수명의 첫 글자는 일반적으로 대문자로 시작한다.

- 생성자에 매개변수가 없으면 생성자를 호출할 때 전달인자 목록과 괄호를 생략할 수 있다.  var o = new Object;

- 생성자를 호출하면 생성자의 프로토타입 속성을 상속받은 새로운 빈 객체가 생성된다.  생성자 함수는 객체를 초기화하고 새로 생성된 이 객체는 호출 컨텍스트로 사용된다.

- 생성자는 새로 생성된 객체를 this 키워드로 참조할 수 있다.

- 생성자 함수는 보통 return 키워드를 사용하지 않는다. 일반적으로 생성자 함수는 새 객체를 초기화하고 생성자 함수 몸체의 끝에 이르면 암시적으로 그 객체를 반환한다. 

- 만약 생성자가 return 문을 사용하여 명시적으로 어떤 객체를 반환하면, 반환된 객체가 생성자 호출 표현식의 값이 되며, 생성자가 반환 값 없이 return 구문만을 사용하거나 원시 형식 값을 반환하면, 그 반환 값은 무시되고 새로 생성된 객체가 호출 표현식 값으로 사용된다. 

 

this 키워드

- 자바스크립트에서 함수를 호출할 때 기존 매개변수로 전달되는 인자 값에 더해 arguments 객체 및 this 인자가 함수 내부로 암시적으로 전달된다. 

- 현재 객체를 참조할 때 this키워드 사용하며, 일반적으로 this는 메소드에서 호출하는 객체를 참조한다.

- 객체의 프로퍼티는 점(.)이나 괄호([])로 접근할 수 있다.

더보기
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">

<script type="text/javascript">
// 객체의 메소드를 호출할 때 메소드 내부 코드에서 사용한 this : 해당 메소드를 호출한 객체
var obj = { // 객체 생성. 일회성. 주로 속성값 보존을 위해 사용
		name : '김자바',
		msg : function() {
			console.dir(this);
			console.log(this.name); // this는 msg() 메소드를 호출한 객체
		}
};

obj.msg();

// 생성자 함수를 호출할 때의 this : 새로 생성되는 객체
function Test(arg) {
	this.name = arg;
	this.getName = function() {
		return this.name;
	};
}

var obj2 = new Test('자바');
console.log( obj2.getName() );

// 함수를 호출할 때의 this
var userName = '스프링'; // 전역 변수. 전역변수는 자동으로 window의 속성이 된다.
// console.log(userName); // 스프링
console.log(window.userName); // 스프링

// sayUser()를 호출할 때 this는 전역 객체(window)에 바인딩
var sayUser = function() {
	console.log( this.userName, userName, window.userName );
}
sayUser();

</script>


</head>
<body>

<h3>객체- this</h3>

</body>
</html>

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">

<script type="text/javascript">
// 객체의 메소드를 호출할 때 메소드 내부 코드에서 사용한 this : 해당 메소드를 호출한 객체
var obj = { // 객체 생성. 일회성. 주로 속성값 보존을 위해 사용
		name : '김자바',
		msg : function() {
			console.dir(this);
			console.log(this.name); // this는 msg() 메소드를 호출한 객체
		}
};

obj.msg();

// 생성자 함수를 호출할 때의 this : 새로 생성되는 객체
function Test(arg) {
	this.name = arg;
	this.getName = function() {
		return this.name;
	};
}

var obj2 = new Test('자바');
console.log( obj2.getName() );

// 함수를 호출할 때의 this
var userName = '스프링'; // 전역 변수. 전역변수는 자동으로 window의 속성이 된다.
// console.log(userName); // 스프링
console.log(window.userName); // 스프링

// sayUser()를 호출할 때 this는 전역 객체(window)에 바인딩
var sayUser = function() {
	console.log( this.userName, userName, window.userName );
}
sayUser();

</script>


</head>
<body>

<h3>객체- this</h3>

</body>
</html>

 

 

 

- this 바인딩

 · 객체의 메소드를 호출할 때 this : 해당 메소드를 호출한 객체

 · 함수를 호출할 때 this : 전역 객체

 · 생성자 함수를 호출할 때 this : 새로 생성되는 객체

 

 

form 요소의 이벤트 핸들러에서의 this : 이벤트를 발생시킨 객체

더보기
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">

<script type="text/javascript">
function send() { // document 는 body라고 생각하면 됨
	var f = document.myForm;
	var name = f.name.value;
	var kor = f.kor.value;
	var eng = f.eng.value;
	var mat = f.mat.value;
	
	alert(name + ":" + kor + ":" + eng + ":" + mat);
}

function validate(obj) {
/*	
	if(! /^(\d){1,3}$/.test(obj.value) ) {
		obj.focus;
		return;
	}
*/
	if(isNaN(obj.value) || parseInt(obj.value) < 0 || parseInt(obj.value) > 100) {
		alert("점수는 0~100 사이만 가능합니다.");
		obj.focus();
		return;
	}
}

</script>

</head>
<body>

<h3>form 요소의 이벤트 핸들러에서의 this : 이벤트를 발생시킨 객체 자기 자신</h3>
<form name="myForm">
	<p> 이름 : <input type="text" name="name"></p>
	<p> 국어 : <input type="text" name="kor" onchange="validate(this);"></p>
	<p> 영어 : <input type="text" name="eng" onchange="validate(this);"></p>
	<p> 수학 : <input type="text" name="mat" onchange="validate(this);"></p>
	<p>
		<button type="button" onclick="send()">확인</button>
	</p>
</form>

</body>
</html>

 

form 요소의 안에서의 this.form : 현재 객체의 부모 form을 나타냄

더보기
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">

<script type="text/javascript">
function send(f) { // f는 document.myForm 을 말함
	var name = f.name.value;
	var kor = f.kor.value;
	var eng = f.eng.value;
	var mat = f.mat.value;
	
	alert(name + ":" + kor + ":" + eng + ":" + mat);
}


</script>

</head>
<body>

<h3>form 요소의 안에서의 this.form : 현재 객체의 부모 form을 나타냄</h3>
<form name="myForm">
	<p> 이름 : <input type="text" name="name"></p>
	<p> 국어 : <input type="text" name="kor"></p>
	<p> 영어 : <input type="text" name="eng"></p>
	<p> 수학 : <input type="text" name="mat"></p>
	<p>
		<button type="button" onclick="send(this.form)">확인</button>
	</p>
</form>

</body>
</html>

 

객체 프로퍼티

- 객체의 프로퍼티는 객체의 특징을 규정한다.

- 프로퍼티 이름은 유효한 자바스크립트 문자열이거나 문자열로 변환이 가능한 어떤 것 또는 빈 문자열도 가능하다.

- 자바스크립트 식별자(identifier)로 적합하지 않으면(하이픈, 빈칸을 포함, 숫자로 시작하는 이름 등), 대괄호를 이용한 표기법으로만 접근이 가능하다.

- 프로퍼티에 접근해서 객체의 기존 프로퍼티 값을 갱신할 수 있다.

- 객체가 생성된 후에도 동적으로 프로퍼티를 생성해서 해당 객체에 추가가 가능하다.

- 상속 받지 않은 객체의 프로퍼티는 delete 연산자를 이용해 삭제하며, 삭제된 속성은 undefined로 설정한다.

delete objectName.propertyName;

- 객체 프로퍼티 접근은 도트 표기법, 대괄호 표기법이 있다.

ec) objectName.propertyName, objectName["propertyName"]

 

객체 - 프로퍼티 동적 추가

더보기
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<script type="text/javascript">
var obj = {
	name:'자바',
	city:'서울'
};

console.log(obj.name);
console.log(obj.city);
console.log(obj.age); // 없는 속성은 undefined. 에러가 아님

// 동적 속성 추가
obj.age = 10;
console.log(obj.age);

// 속성 제거
delete obj.city;
console.log(obj.city);

</script>
</head>
<body>

<h3>객체 - 프로퍼티 동적 추가</h3>

</body>
</html>

 

객체 프로퍼티 접근 및 나열

더보기
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<script type="text/javascript">
var obj = {
	name:'이자바',
	age:20,
	msg: function() {
		return this.age>=19? '성인':'미성년자';
	}
};

// 객체 속성 접근
console.log(obj.name); // 도트 표기법 접근
console.log(obj['name']); // 대괄호 표기법으로 접근

// 메소드 접근
console.log(obj.msg());

// 객체의 프로퍼티 나열
for(var ob in obj) { // ob : 프로퍼티이름
	console.log(ob, obj[ob]);
}

console.log('name' in obj); // true. 객체에 속성이 존재하는지 확인
console.log('subject' in obj); // false

// console.log(obj.name);
// 간단한 표현
with(obj) {
	console.log(name);
	console.log(age);
}

</script>
</head>
<body>

<h3>객체 - 프로퍼티 접근 및 나열</h3>

</body>
</html>

 

정적 메소드(static method)

- 생성자의 속성에 직접 지정된 메소드를 정적 메소드(static method)라고 한다.

- Number.isNaN, Object.getPropertyOf 등의 함수들은 모두 정적 메소드이다.

- 정적 메소드는 특정 인스턴스에 대한 작업이 아닌, 해당 생성자와 관련된 일반적인 작업을 정의할 때 사용된다. 

 

생성자 함수에 추가하는 프로퍼티나 메소드

더보기
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<script type="text/javascript">
/*
 - 생성자 함수에 추가하는 프로퍼티나 메소드 : 프로토타입에 추가하므로 생성자를 통해 생성된 모든 다른 객체에 적용
 - 프로토타입
	객체는 부모 객체의 프로퍼티나 메소드를 상속 받아 사용할 수 있으며, 
	이러한 부모 객체를 프로토 타입 객체 또는 프로토타입이라 함 
*/ 
function User(name) {
	this.name = name;
	this.age = 20; // 기본값을 가질 수 있음
	this.state = function() {
		return this.age >= 19 ? '성인':'미성년자';
	};
}

console.dir(User);

var obj = new User('홍길동');
console.log(obj.name, obj.state() );

</script>

</head>
<body>

<h3>생성자 함수에 추가하는 프로퍼티나 메소드</h3>

</body>
</html>

 

정적 메소드

더보기
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">

<script type="text/javascript">
// 정적 메소드 : 생성자에 직접 지정된 메소드
function User(name) {
	this.name=name;
	this.getName = function() {
		return this.name;
	};
}

// 클래스 안에 정적 메소드 추가
// 정적 메소드
User.state = function(age) {
	return age>=19? '성인':'미성년자'; 
	// this가 있을 수 없음. 객체 생성과 상관 없음. this는 정적메소드와 상관없음
};

console.log(User.state(30));
// console.log(User.getName()); // 에러. 정적 메소드가 아님. 객체를 생성해서 호출해야함

var obj = new User('하하하'); // 메모리할당
console.log(obj.getName());

</script>


</head>
<body>

<h3>정적 메소드</h3>

</body>
</html>

 

+ Recent posts