2019. 7. 15. 18:11ㆍjavascript
1. 객체는 새로운 값을 가진 프로퍼티를 생성한다. 이 프로퍼티에 접근하는 방법은 두 가지 방법이 있다,
- 대괄호 표기법 ([])
- 마침표 표기법 (.)
// 객체 리터럴 방식을 통한 foo 객체 생성
var foo = {
name : "foo",
major : "singer"
};
console.log(foo.name); // foo
console.log(foo["name"]); // foo
console.log(foo.nickname); // undefined
// 객체 프로퍼티 갱신
foo.major = "engineer";
console.log(foo.major); // engineer
console.log(foo["major"]; // engineer
// 객체 프로퍼티의 동적 생성
foo.age = 30;
console.log(foo.age); // 30
객체 프로퍼티에 값을 할당할 때 프로퍼티가 이미 있는 경우 해당 프로퍼티의 값이 갱신 되지만 값이 없을 경우 새로운 프로퍼티가 동적으로 생성된 후 값이 할당된다.
// 대괄호 표기법만을 사용해야 할 경우
foo["full-name"] = "foo bar";
console.log(foo["full-name"]); // foo bar
console.log(foo.full-name); // undefined
console.log(foo.full); // undefined
console.log(name); // undefined
일반적으로 마침표 표기법을 사용하여 프로퍼티에 접근하는 방법을 사용하지만 프로퍼티가 표현식이거나 예약어일 경우 대괄호 표기법만을 사용해야 한다. 위의 경우 접근하고자 하는 프로퍼티가 "full-name"이다. "full-name"에는 "-" 연산자가 포함되어 있다.
만약 이경우에 마침표 표기법을 사용하면 NaN값이 출력된다. NaN이란 수치 연산을 해서 정상적인 값을 얻지 못할 때 출력되는 값이다.
full.full(foo객체의 full프로퍼티의 값) - name (name변수)으로 인식하여 undefined - undefined의 연산이 되므로 결과 값이 NaN으로 출력된다.
2. 객체 프로퍼티 삭제
delete 연산자를 이용해 즉시 삭제할 수 있지만 프로퍼티만 삭제할 뿐 객체 자체를 삭제하지는 못한다.
// 객체 리터럴을 통한 foo객체 생성
var foo = {
name : "foo",
nickname : "babo"
};
console.log(foo.nickname); // babo
delete foo.nickname; // nickname 프로퍼티 삭제
console.log(foo.nickname); // undefined
delete foo; // foo 객체 삭제 시도
console.log(foo.name); //foo
3. 참조 타입의 특성
자바스크립트에서 기본 데이터 타입을 제외한 모든 값은 객체로 취급된다. 그리고 객체는 참조 타입이라고 부른다. 개체의 모든 연산이 참조값으로 처리되기 때문이다.
var objA = {
val : 40;
};
var objB = objA;
console.log(objA.val); // 40
console.log(objB.val); // 40
objB.val = 50;
console.log(objA.val); // 50
console.log(objB.val); // 50
objA 변수는 객체 자체를 저장하고 있는 것이 아니라 참조값을 저장하고 있다. objB에 objA를 할당하는것은 참조값을 할당 하는 것이다.
즉 objA와 objB는 동일한 객체를 가리키는 참조값을 가지게 되는 것이다.
3. 객체 비교
동등 연산자를 사용하여 두 객체를 비교할 때도 객체의 프로퍼티 값이 아닌 참조값을 비교한다.
var a = 100;
var b = 100;
var objA = { val : 100 };
var objB = { val : 100 };
var objC = objB;
console.log(a === b); // true
console.log(objA === objB); // false
console.log(objB === objC); // true
동등 연산자는 기본 타입의 경우 값 자체를 비교하지만 객체인 경우 참조값을 비교한다.
objA와 objB는 다른 객체이고 objC는 objB의 같은 객체를 참조한다. 객체의 경우 참조값이 같아야 true가 되기 때문에 objA와 objB는 false가 되는 것이고 objB와 objC는 true가 되는 것이다.
4. 참조에 의한 함수 호출 방식
기본 타입의 경우 값에 의한 호출 (Call By value) 방식으로 동작한다. 함수를 호출할 때 인자를 기본 타입의 값으로 넘기는 경우 함수의 매개 변수로 복사 된 값이 전달되기 때문에 함수 내부에서 값을 변경한다 하더라도 실제로 호출된 변수의 값은 변경되지 않는다.
참조 타입의 경우 참조에 의한 호출(Call by Reference) 방식으로 동작한다. 함수를 호출할 때 참조 타입인 객체를 전달할 경우 인자로 넘긴 객체의 참조값이 그대로 함수 내부로 전달되기 때문에 함수 내부에서 참조값을 이용해서 인자로 넘긴 실제 객체의 값을 변경할 수 있는 것이다.
var a = 100;
var objA = { value:100 };
function changeArg(num, obj){
num = 200;
obj.value = 200;
console.log(num); // 200
console.log(obj); // { value: 200 }
}
changeArg(a, objA);
console.log(a); // 100
console.log(objA); // { value: 200 }
기본 타입인 변수 a의 경우 함수를 지나쳐 나왔을 때 값이 변화되지 않았지만 참조 타입인 변수 objA는 값이 바뀐걸 알 수 있다.
5. 프로토타입
모든 객체는 자신의 부모 역활을 하는 객체와 연결되어 있다. 부모 객체의 프로퍼티를 마치 자신의 것처럼 사용 할 수 있는 특징이 있는데 이러한 부모 객체를 프로토타입 객체(프로토타입) 이라고 부른다.
var foo = {
name : "foo",
age : 30
};
console.log(foo.toString()); // "[object object]"
console.dir(foo);
foo에는 toString() 메서드가 없으므로 에러가 발생해야 하지만 제대로 출력되고 있다. 그 이유는 foo 객체의 프로토타입에 toString()메서드가 이미 정의되어 있기 때문이다.
foo객체를 출력하여 확인 해보면 toString()메서드가 정의되어 있는 것을 확인할 수 있다.
ECMAScript 명세서에는 자바스크립트의 모든 객체는 자신의 프로토타입을가리키는 [[Prototype]]라는 숨겨진 프로퍼티를 가진다고 설명한다. 크롬 브라우저의 _proto_가 이 숨겨진 [[Prototype]] 프로퍼티를 의미한다.
'javascript' 카테고리의 다른 글
Prototype, __proto__, constructor 의 관계 (0) | 2019.07.29 |
---|---|
함수 객체 (0) | 2019.07.19 |
함수 (0) | 2019.07.18 |
배열 (0) | 2019.07.17 |
자바스크립트 데이터 타입 (0) | 2019.07.14 |