Javascript는 객체지향(기반) 언어
자바스크립트를 구성하는 대부분은 객체로 구성되어 있다.
원시타입(문자열, 숫자 등)은 불변의 특징을 가지고 있으며, 이와 반대로 객체는 변한다는(mutable) 특징을 가지고 있다.
그렇다면 원시타입 변수를 불변으로 만들어야 할 필요가 있을까?
그 이유는, 값을 그 자리에서 바꿔버리게 되면 나중에 잘못되었을 때 어디서 잘못되었는지 추적하기가 어려워진다.
따라서 불변으로 새로운 주소에 값을 주어, 추적하기 쉬워진다.
정리하자면 값이 바뀌게 되는 이력을 추적하기 좋기 때문이다.
객체는 왜 mutable한 특성으로 만들었을까?
객체의 경우 원시타입보다 크기가 크고, 이를 불변으로 하게 되면 메모리의 효율성이 떨어지기 때문이다.
Javascript의 객체 (객체 literal)
객체란?
0개 이상의 property의 집합을 의미한다. 각 property는 key와 value의 쌍으로 이루어져 있다.
아래와 같이 JSON 형태로 객체를 만들 수 있다.
# JSON 형태로 객체를 만들 수 있다.
var person = {
'name': '홍길동',
'age': 20
}
var person = {
name: '홍길동',
age: 20
}
property key
property key는 문자열과 symbol 값이 사용될 수 있다.
위 코드에서 property key에 해당되는 부분은 name, age이다.
property value
property value는 Javascript value로 의미되는 모든것이 사용될 수 있다. (함수가 나올 수 있다 -> 메소드)
위 코드에서 property value에 해당되는 부분은 '홍길동', 20이다.
Javascript 객체 생성
※ 객체를 생성하려면 어떻게 해야할까?
1. 객체 literal (가장 간단한 방법이지만, 똑같은 형태의 객체를 만들 때 비효율적이다)
2. Object 생성자 함수
3. 사용자가 만든 생성자 함수 (User defined)
4. Object.create( ) 메서드 이용
5. 'ES6'에서 만든 -> class
객체 literal
각 property는 key와 value의 쌍으로 이루어져 있다.
Property의 key는 문자열 혹은 Symbol로 구성될 수 있다.
식별자 명령규칙(naming rule)에 부합하는 경우에는, key 값에 따옴표(" ") 생략이 가능하다.
하지만 특수문자를 포함하는 등 naming rule에 맞지 않는다면, ' ' 를 포함해서 key로 작성할 수 있다.
var obj = {
'name': '홍길동',
'printname': function myPring(){
console.log(`내 이름은 ${this.name}`); // this는 현재 사용하는 객체를 지칭한다
}
};
var obj = {
name: '홍길동',
printname: function myPring(){
console.log(`내 이름은 ${this.name}`);
}
};
// naming rule에 맞지 않는 key를 쓰고자 할 때
// "!myphone" : "010-3030-3030"
// 10 : 010 에서 key에 해당하는 10은 자동으로 문자열로 인식한다
Property의 동적 추가와 삭제
동적추가 | . (dot rotation) [ ] (bracket rotation) |
동적삭제 | delete 키워드 이용 |
var obj = {
myName: '홍길동'
}
obj.myAge = 20;
// obj.!myPhone = "010-0000-0000"; 이런 경우
// 식별자 naming rule에 맞지 않은 key를 사용하고자 할 때
// [ ] 안에는 항상 "문자열" 형식으로 사용
obj['!myPhone'] = '010-0000-0000';
obj['myAge'] = "38";
console.log(obj);
// 삭제
delete obj.myAge;
console.log(obj);
※ 기타 property key 추가 방법
var obj = {
10: 100,
let: '권장되지 않아요!',
myName: '홍길동',
"!myName": "김길동",
myName: '키 값이 중복되어도 사용 가능하다, 먼저 나온게 날라간다(권장X)'
}
console.log(obj);
console.log(obj.myAdress);
//키가 없기 때문에 에러가 나와야 하는데, undefiend 값이 리턴된다
※ ES6에서 추가된 객체 literal 확장
식별자를 가지고 key로 쓰고, 값을 value로 사용하는 확장된 객체 리터럴 표현 방식이다. (축약 표현)
let x = 1;
let y = 2;
const obj = {x, y}
console.log(obj);
// { x: 1, y: 2 }
let myObj = {
name: '홍길동',
printName() {
console.log(this.name);
}
// 함수를 축약된 메서드로 표현할 수 있다
}
myObj.printName()
원시값 VS 객체
var obj = {name: '홍길동'}
원시값 | 객체 |
immutable | mutable |
유사배열객체 (Array-like-Object)
let myStr = 'Hello';
// primitive type을 마치 객체(배열)처럼 사용
console.log(myStr[0]); // H
console.log(myStr.length); // 5
myStr은 원래 원시타입으로 값을 가지고 있었는데, myStr[0] 코드가 수행되는 순간 객체가 내부슬롯에 생성된다.
기존의 str이 만들어진 객체를 참조하게 되고, 원시타입인 myStr의 value가 객체 맨 위에 들어가게 된다.
그리고 그 밑에 length를 포함한 키(인덱스) : 값의 형식의 객체가 생성되게 된다.
코드 한 줄이 끝나고, 값의 사용이 끝나게 되면 내부 슬롯의 값이 바로 날라가게 된다.
let myStr = 'Hello';
myStr[0] = 'h';
console.log(myStr); // Hello
여기서 hello가 아닌 Hello가 출력되는 이유는 바로 위의 이유 때문이다.
myStr[0] = 'h';
코드가 실행되었을 때, myStr 값 자체가 바뀌는 것이 아니라 밑에 있는 해당 인덱스의 값이 바뀌기 때문에 결과는 Hello가 출력되는 것이다. 이를 통해 원시타입인 myStr은 불변이라는 것을 확인할 수 있다.
객체의 복사
하나의 객체를 여러개의 식별자가 공유해서 사용할 수 있다.
문제는 하나의 객체가 바뀌면 그것을 참조하고 있는 다른 식별자들 또한 바뀌게 된다.
let person = {name: 'Lee'}
let copy = person
'Kakao Cloud School > 카카오클라우드스쿨 수업' 카테고리의 다른 글
[Javascript] 데이터 타입 (0) | 2022.07.05 |
---|---|
[Javascript] History of Javascript, ES6 (0) | 2022.07.05 |
[Javascript] 객체(2) (0) | 2022.07.05 |
[Javascript] 스코프 (0) | 2022.07.05 |
[Javascript] 함수 (0) | 2022.07.05 |