- 자바스크립트에서 원시 타입을 제외한 모든 나머지 값들(함수 배열 정규표현식 등)은 객체.
- 객체는 key 와 value 로 구성된 property 의 집합
- 프로퍼티 값이 함수인 경우 일반 함수와 구분하기 위해 메소드라 부름 (자바스크립트의 함수는 일급객체(참고)이므로 값으로 취급 가능)
- 객체는 데이터를 의미하는 프로퍼티와 데이터를 참조하고 조작할 수 있는 동작(메소드)로 구성된 집합
- 프로퍼티 및 메소드를 모두 포함할 수 있어 하나의 단위로 구조화하기 유용
- 프로토타입을 상속받아 객체지향의 상속을 구현한다
[프로퍼티]
- 프로퍼티 키를 중복 선언시 나중에 선언한 프로퍼티가 먼저 선언한 프로퍼티를 덮어씀
- 프로퍼티간 순서를 보장하지 않음
[메소드]
- 프로퍼티 값이 함수인 경우 메소드라 부름
- 객체에 제한되어 있는 함수를 의미
[객체 생성 방법]
1. 객체 리터럴
- 중괄호 사용하여 생성
- 비어있는 객체 생성 가능 ex) var empty = {};
1
2
3
4
5
6
7
|
var person = {
name : 'Lee',
gender : 'male',
sayHello : function(){
console.log('My name is' + this.name);
}
}
|
cs |
2. Object 생성자 함수
- new 연산자와 Object 생성자 함수를 호출하여 빈 객체 생성 가능
- 생성자 함수의 이름은 파스칼 케이스를 사용하는게 일반적
- 객체가 소유하고 있지 않은 프로퍼티 키에 값을 할당하면 해당 객체에 프로퍼티를 추가하고 값을 할당, 이미 존재하는 프로퍼티 키에 새로운 값을 할당하면 해당 값으로 변경
* Object 생성자 함수 사용보단 객체 리터럴 사용 (객체 리터럴 사용시 내부적으로 Object 생성자 함수를 사용하여 객체를 생성하므로)
3. 생성자 함수
프로퍼티 값만 다른 객체를 여러개 생성할 때 객체 리터럴 및 Object 생성자 함수를 사용한다면 아래와 같이 코드량이 많아지고 불편
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
var person1 = {
name : 'Lee',
gender : 'male',
sayHello : function(){
console.log('My name is' + this.name);
}
}
var person2 = {
name : 'Kim',
gender : 'female',
sayHello : function(){
console.log('My name is' + this.name);
}
}
|
cs |
이를 아래와 같이 생성자 함수를 사용하면 간편
1
2
3
4
5
6
7
8
9
10
11
|
function Person(name, gender){
this.name = name;
this.gender = gender;
this.sayHello = function(){
console.log('Hi! My name is ' + this.name);
}
}
var person1 = new Person('Lee', 'male');
var person2 = new Person('Kim', 'female');
person1.sayHello();
person2.sayHello();
|
cs |
- 생성자 함수명은 대문자로 시작하여 생성자임을 인식하도록 도움을 줌
- 프로퍼티 또는 메소드 앞에 기술한 this는 생성할 인스턴스(비어있는 새로운 객체)를 의미(new 연산자와 함께 함수를 호출시 this 바인딩이 다르게 동작)
- this 에 바인딩되어있는 프로퍼티와 메소드는 외부에서 참조가 가능, 생성자 함수 내에서 선언된 일반 변수는 외부에서 참조 불가 : 생성자 함수 내부에서 자유롭게 접근이 가능하나 외부에서 접근은 불가 (아래 참고)
1
2
3
4
5
6
7
8
9
10
11
|
function Person(name, gender){
var married = true;
this.name = name;
this.gender = gender;
this.sayHello = function(){
console.log('Hi! My name is ' + this.name);
}
}
var person = new Person('Lee', 'male');
console.log(person.gender); // 'male'
console.log(person.married); // 'undefined'
|
cs |
※ 자바의 생성자와 다르게 형식이 정해져 있지 않고, 기존 함수와 동일한 방법으로 선언하고 new 연산자를 붙여 호출하면 생성자 함수로 동작
※ 생성자 함수가 아닌 일반 함수에 new 연산자를 붙일 경우 생성자 함수처럼 동작 가능하다는 것을 의미. 따라서 생성자 함수의 첫문자는 대문자로 명명하여 혼란 야기를 방지
※ new 연산자와 함께 함수를 호출하면 this 바인딩이 다르게 동작
[ new 연산자와 함께 생성자 함수 호출시 동작 순서 ]
1. 빈 객체 생성 및 this 바인딩
- 생성자 함수의 코드가 실행되기 전 비어있는 객체가 생성된다
- 생성자 함수 내에서 사용하는 this 는 이 비어있는 객체를 가리킨다.
- 생성된 빈 객체의 프로토타입 객체는 생성자 함수의 prototype 프로퍼티가 가리키는 객체.
2. this를 통한 프로퍼티 생성
- 생성된 빈 객체에 this를 사용하여 프로퍼티나 메소드 생성 가능
3. 생성된 객체 반환
- this 에 바인딩된 객체 자동 반환
[ 객체 프로퍼티 선언 및 접근 ]
[ 프로퍼티 키 선언 ]
- 프로퍼티 키에 표현식(- 연산자 등)이 존재하는 경우 대괄호로 묶어야 함 otherwise, ReferenceError 발생, 예약어는 당연히 사용하면 안된다
ex: var person = {first-name : 'gildong'} >> ReferenceError
[ 프로퍼티 키 접근 ]
- 마짐표 . 표기법: 프로퍼티 키가 유효(표현식(- 연산자 등)이 있는 경우 무효), 예약어가 아닌 경우 마침표/대괄호 표기법 모두 사용 가능
- 대괄호 [] 표기법: 프로퍼티 키가 유효한 값이 아니거나, 예약어인 경우 대괄호 내에 들어가는 프로퍼티 이름은 반드시 문자열이어야 함
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
var person = {
'first-name': 'gildong',
'last-name': 'Hong',
gender: 'male',
1: 10
}
console.log(person.first-name); // NaN : undefined - undefined
console.log(person[first-name]); // ReferenceError
console.log(person['first-name']); // 'gildong' 대괄호 표기법 대괄호 안이 반드시 문자열, 유효하지 않은 프로퍼티 키는 대괄호를 사용하여 읽음
console.log(person.gender); // 'male' 유효한 프로퍼티 키는 대괄호, 마짐표 표기법 모두를 사용하여 읽기 가능
console.log(person[gender]); // ReferenceError
console.log(person['gender']); // 'male' 대괄호 표기법 대괄호 안이 반드시 문자열, 유효한 프로퍼티 키는 대괄호, 마짐표 표기법 모두를 사용하여 읽기 가능
console.log(person['1']); //10 대괄호 표기법 대괄호 안이 반드시 문자열, 유효하지 않은 프로퍼티 키는 대괄호를 사용하여 읽음
console.log(person[1]); //10
console.log(person.1); //SyntaxError
|
cs |
[ 프로퍼티 값 수정 ]
- 객체가 갖고 있는 프로퍼티에 새로운 값 할당시 값이 수정됨
ex) person.gender = 'female';
[ 프로퍼티 생성 ]
- 객체가 소유하고 있지 않은 프로퍼티 키와 값 할당시 새로운 프로퍼티 추가됨
ex) person.age = 30;
[ 프로퍼티 삭제 ]
- delete 키워드를 사용하여 객체 프로퍼티를 삭제, 이때 피연산자는 프로퍼티 키.
ex) delete person.gender;
[ 프로퍼티 값 출력 ]
1
2
3
4
5
6
|
for(var prop in person){
console.log(prop + ':' +person[prop]);
}
for(var idx in array){
console.log(idx + ":" +array[idx]);
}
|
cs |
- for in문 사용하여 객체에 포함된 모든 프로퍼티 루프 출력이 가능
- for in문은 array 에서 사용을 삼가. 배열 요소만을 순회하지 않음
※ for of 사용 (ES6)
[ pass by reference ]
객체 타입은 원시타입과 달리 동적으로 변화할 수 있으며 어느정도 메모리 공간을 확보해야 하는지 예측 불가하기 때문에 런타임에 메모리 공간을 확보하고 메모리의 힙영역에 저장된다.
1
2
3
4
5
6
7
|
var foo = {
val : 10
}
var bar = foo;
console.log(foo.val, bar.val); // 10 10
bar.val = 20;
console.log(foo.val, bar.val); // 20 20
|
cs |
(위의 두 변수 모두 동일한 객체의 참조주소를 참조한다 (java의 참조객체와 동일))
참고 : https://poiemaweb.com/js-object#2-%EA%B0%9D%EC%B2%B4-%EC%83%9D%EC%84%B1-%EB%B0%A9%EB%B2%95
'front > javascript' 카테고리의 다른 글
높이 자동조절 textarea 구현 (auto-resizing textarea) (0) | 2020.12.15 |
---|---|
[javascript] promise 를 사용한 비동기 후처리 (0) | 2020.05.04 |
[jQuery] radio에 onchange 적용하기(선택받지 못한 radio 값 지우기) (0) | 2019.11.15 |
[javascript] strict mode(엄격모드) 란? (0) | 2019.11.15 |
[javascript] 자바스크립트 this 정리 (0) | 2019.11.15 |