본문 바로가기
front/javascript

[javascript] 자바스크립트의 객체

by 펭귄대장 2019. 12. 2.

- 자바스크립트에서 원시 타입을 제외한 모든 나머지 값들(함수 배열 정규표현식 등)은 객체.
- 객체는 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'
  110 
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

반응형

댓글0