-
0. 객체
- 객체는 몇 가지 특수한 기능을 가진 연관배열이다
- 객체는 프로퍼티(키-값)을 저장한다
- 프로퍼티 키는 문자열이나 심볼이어야 한다. 보통은 문자열이다
- 값은 어떤 자료형도 가능하다
1. 계산된 프로퍼티
- 객체를 만들 때 객체 리터럴 안의 프로퍼티 키가 대괄호로 둘러 싸여 있는 경우, 이를 계산된 프로퍼티라고 부른다.
let fruit = prompt("어떤 과일을 구매하시겠습니까?", "apple"); let bag = { [fruit]: 5, // 변수 fruit에서 프로퍼티 이름을 동적으로 받아 온다 alert( bag.apple ); // fruit에 "apple"이 할당되었다면, 5가 출력된다.
2.'in' 연산자로 프로퍼티 존재 여부 확인하기
- 연산자 in을 사용하면 프로퍼티 존재여부를 확인할 수 있다
let user = { name: "John", age: 30 }; alert( "age" in user ); // user.age가 존재하므로 true가 출력된다 alert( "blabla" in user ); // user.blabla는 존재하지 않기 때문에 false가 출력된다.
3. 객체 정렬방식
- 정수 프로퍼티는 자동으로 정렬. //정수프로퍼티: 변형없이 정수에서 왔다갔다 할 수 있는 문자열
- 그 외의 프로퍼티는 객체에 추가한 순서 그대로 정렬.
let codes = { "49": "독일", "41": "스위스", "44": "영국", // .., "1": "미국" }; for (let code in codes) { alert(code); // 1, 41, 44, 49 }
4. 참조에 의한 객체 복사
- 객체와 원시타입의 근본적인 차이 중 하나는 객체는 '참조에 의해 ' 저장되고 복사 된다.
- 즉 변수엔 객체에대한 '참조 값'이 저장 된다
- 새로운 객체를 만들어주는 Object.assign이라는 내장 함수가 있다.
let user = { name: "John", age: 30 }; let clone = Object.assign({}, user); user === clone // false
5. 가비지 컬렉션
- 자바스크립트는 '도달 가능성'이라는 개념을 사용해 메모리 관리를 수행한다.
- 루트가 참조하는 값이나 체이닝으로 루트에서 참조할 수 있는 값은 도달 가능한 값이다1. let user = { name: "John" }; 2. user = null; //이제 John은 도달할 수 없는 상태. 따라서 가비지 컬렉션은 John을 메모리에서 삭제.
6.메서드와 this
- this 값은 런타임시에 결정된다. 컨텍스트에 따라 달라진다.
- 즉 동일한 함수라도 다른 객체에서 호출했다면 'this'가 참조하는 값이 달라진다.let user = { name: "John" }; let admin = { name: "Admin" }; function sayHi() { alert( this.name ); } // 별개의 객체에서 동일한 함수를 사용함 user.f = sayHi; admin.f = sayHi; // 'this'는 '점(.) 앞의' 객체를 참조하기 때문에 // this 값이 달라짐 user.f(); // John (this == user) admin.f(); // Admin (this == admin)
- this가 런타임 시 결정되면 좋은 점은 함수를 하나만 만들어 여러 객체에서 재사용할 수 있는 점.
- but, 이런 유연함이 실수로 이어질 수 있다.7. 'new' 연산자와 생성자 함수
- "new" 연산자와 생성자 함수를 사용하면 유사한 객체 여러개를 쉽게 만들 수 있다.
- 생성자 함수
1. 함수이름의 첫글자는 대문자
2. "new" 연산자를 붙여 실행function User(name) { this.name = name; this.isAdmin = false; } let user = new User("Jack"); alert(user.name); // Jack alert(user.isAdmin); // false
- new User(...)를 써서 함수를 실행하면 아래와 같이 작동합니다
1. 빈 객체를 만들어 this에 할당
2. 함수 본문을 실행.
3. this를 반환
- 재사용할 필요가 없는 복잡한 객체를 만들때는 new function(){...}을 사용하자let user = new function() { this.name = "John"; this.isAdmin = false; } //위 생성자는 어디에도 저장하지 않음.
- 생성자 함수엔 보통 return 문이 없는데, 반환해야 할 것들은 모두 this에 저장 되고, this는 자동반환 되기때문이다.
- 만약 return 문이 있다면?
1. 객체를 return 한다면, this 대신 객체가 반환
2. 원시형을 return 한다면, return 문 무시function BigUser() { this.name = "John"; return { name: "Godzilla" }; // <-- this가 아닌 새로운 객체를 반환함 } alert( new BigUser().name ); // Godzilla
8. 옵셔널 체이닝 '?.'
- 옵셔널 체이닝 ?.을 사용하면 프로퍼티가 없는 중첩 객체를 에러 없이 안전하게 사용 가능
- 옵셔널 체이닝이 등장하기 전에는 값이 존재하는 지 확인 하기 위해 &&연산자를 사용하곤 하였는데, 코드가 길어지는 단점이 있었다.
- ?.은 '앞'의 평가 대상이 undefined나 null 일 경우 멈추고 undefined를 반환한다.let user = null; let x = 0; user?.sayHi(x++); // 아무 일도 일어나지 않는다 alert(x); // 0, x는 증가하지 않음.
let user1 = { admin() { alert("관리자 계정입니다."); } } let user2 = {}; user1.admin?.(); // "관리자 계정입니다." 출력 user2.admin?.();
let user1 = { firstName: "Violet" }; let user2 = null; // user2는 권한이 없는 사용자라고 가정해보자 let key = "firstName"; alert( user1?.[key] ); // Violet alert( user2?.[key] ); // undefined
- delete와도 조합해 사용할 수 있다. (이전에는 무조건 먼저 if문을 쓰고 delete문을 사용했었는데...)
let user1 = { firstName: "Violet" }; let user2 = null; // user2는 권한이 없는 사용자라고 가정해보자 let key = "firstName"; alert( user1?.[key] ); // Violet alert( user2?.[key] ); // undefined
- but, ?.은 읽기, 삭제하기에는 사용 가능 하지만 쓰기에는 사용할 수 없다.
user?.name = "Violet"; // SyntaxError: Invalid left-hand side in assignment // 에러가 발생하는 이유는 undefined = "Violet"이 되기 때문이다.
9.심볼형
- 자바스크립트는 객체 프로퍼티 키로 오직 문자형과 심볼형만을 허용한다.
- 심볼은 유일한 식별자를 만들고 싶을 때 사용한다.
- 심볼을 만들 때 심볼 이름이라 불리는 설명을 붙일 수도 있다.
- 심볼은 유일성이 보장되기 때문에, 설명이 동일한 심볼을 여러 개 만들어도 각 심볼 값은 다르다.// 심볼 id에는 "id"라는 설명이 붙인다. let id1 = Symbol("id"); let id2 = Symbol("id"); alert(id1 == id2); // false
- 심볼은 문자형으로 자동형변환 되지 않기 때문에, 만약 반드시 출력을 해주어야 하는 사항이라면 다음과 같이 toString, description메서드를 사용한다.
let id = Symbol("id"); alert(id.toString()); // Symbol(id)가 얼럿 창에 출력됨 let id = Symbol("id"); alert(id.description); // "id" 설명이 출력
- 심볼을 이용해서 '숨김 프로퍼티 '를 만들 수 있다.
- 만약, 서드 파티 코드에서 가지고 온 user라는 객체가 여러개 있고, user를 이용해 어떠한 작업을 해야하는 상황이라서 user 에 식별자를 붙여줘야한다면...let user = { // 서드파티 코드에서 가져온 객체 name: "John" }; let id = Symbol("id"); user[id] = 1; alert( user[id] ); // 심볼을 키로 사용해 데이터에 접근할 수 있습니다
- 문자열 "id"대신 Symbol('id")사용한 이유는?심볼은 유일성이 보장되기때문에, 만약 또 다른 user객체가 있더라도 식별자끼리 충돌 안함.
- 심볼을 사용하면 서드파티 코드가 모르게 user에 식별자를 부여할 수 있음.
- 객체 {...}를 만든 경우 , 대괄호를 사용해 심볼형 키를 만들어야 한다.let id = Symbol("id"); let user = { name: "John", [id]: 123 // "id": 123은 안됨 };
- 심볼은 for...in 반복문, Object.key에서 배제 된다. but, Object.assign()에서는 배제하지않고 복사된다.
- 전역 심볼을 만들기 위해서는 Symbol.for(key)를 사용한다let id = Symbol.for("id"); // 심볼이 존재하지 않으면 새로운 심볼을 만든다. // 동일한 이름을 이용해 심볼을 다시 다시 읽는다. let idAgain = Symbol.for("id"); // 두 심볼은 같습니다. alert( id === idAgain ); // true
- Symbol.keyFor()를 사용하면 전역 심볼 이름을 알 수 잇다
let id = Symbol.for("id"); // 심볼이 존재하지 않으면 새로운 심볼을 만든다. // 동일한 이름을 이용해 심볼을 다시 다시 읽는다. let idAgain = Symbol.for("id"); // 두 심볼은 같습니다. alert( id === idAgain ); // true
*참조 : ko.javascript.info/
'프로그래밍 > Js' 카테고리의 다른 글
new Function 문법 (0) 2021.07.05 객체로서의 함수와 기명 함수 표현식 (0) 2021.07.02 JS - 추상관계비교 (0) 2021.02.24 JS-parseInt 문자열→숫자로 파싱 (0) 2021.02.22 JS - Boolean 타입 강제변환 (0) 2021.02.18