객체란, 다양한 타입의 값(원시값 or 다른 객체)을 하나의 단위로 구성한 복합적인 자료구조
객체를 변수에 할당하면 변수에는 '참조 값'이 저장된다.
객체는 0개 이상의 프로퍼티로 구성된 집합으로, 프로퍼티는 key-value의 조합으로 구성되어 있다.
let user = new Object(); // '객체 생성자' 문법
let user = {}; // '객체 리터럴' 문법
객체 리터럴의 { } 안에는 'key(식별자)-value'의 쌍으로 구성된 property가 들어간다.
let user = { // 객체
name: "John", // 키: "name", 값: "John"
age: 30 // 키: "age", 값: 30
};
const 키워드로 선언된 객체는 그 객체 자체는 변경하지 못하지만, 객체의 '참조값'을 가리키고 있으므로 객체의 프로퍼티는 수정할 수 있다.
.
은 공백이 없고, 숫자로 시작하지 않으며 $
와 _
가 없는 유효한 변수 식별자에만 사용할 수 있다.
키가 유효한 변수 식별자가 아닌 경우, 점 표기법 대신 어떤 문자열이든 동작 가능한 대괄호 표기법을 사용하여 객체를 표현할 수 있다.
let user = {};
// set
user["likes birds"] = true;
// get
alert(user["likes birds"]); // true
// delete
delete user["likes birds"];
또한, key는 런타임에 평가되기 때문에 사용자 입력값 변경 등 평가가 끝난 이후의 결과를 프로퍼티 키로 사용할 수 있다. 점 표기법은 실시간으로 변하는 key를 찾는 데 사용할 수 없다.
key, value의 이름이 동일한 경우 변수명만 써도 프로퍼티를 설정할 수 있다.
let user = {
name, // name: name 과 같음
age: 30
};
자바스크립트 객체는 다른 언어와 달리 존재하지 않는 프로퍼티에 접근하려 해도 에러가 발생하지 않고 undefined
를 반환하는데, 연산자 in을 사용해서 프로퍼티의 존재 여부도 확인할 수 있다.
let user = {};
alert( user.noSuchProperty === undefined ); // true는 '프로퍼티가 존재하지 않음'을 의미
let user = { name: "John", age: 30 };
alert( "age" in user ); // user.age가 존재하므로 true 출력
alert( "blabla" in user ); // user.blabla는 존재하지 않기 때문에 false 출력
원시값과 달리 객체는 참조에 의해(by reference) 저장되고 복사된다.
원시값은 그 값 자체가 메모리 주소에 할당되어 저장되고 복사된다.
그러나 객체는 객체가 저장된 메모리 주소에 객체에 대한 '참조 값'이 저장된다. 객체 내부의 값이 저장되는 것이 아니다.
따라서 객체를 복사할 때 객체의 '참조 값'이 복사될 뿐, 객체가 복사되는 것은 아니다.
let a = {};
let b = a; // 참조에 의한 복사
alert( a == b ); // true, 두 변수는 같은 객체를 참조하고 있다.
alert( a === b ); // true
let a = {};
let b = {}; // 똑같이 생겼으나 서로 다른 메모리 주소를 참조하고 있는 독립된 두 객체
alert( a == b ); // false
let user = {
name: "John",
sizes: {
height: 182,
width: 50
}
};
alert( user.sizes.height ); // 182
위같은 경우 clone.sizes = user.sizes
으로 객체를 복사할 수 없다. user.sizes
가 객체이기 때문에 참조 값이 복사된다.
const obj1 = { a: 1, b: 2};
const obj2 = obj1;
console.log( obj1 === obj2 ); // true
const obj1 = { a:1, b:2 };
const obj2 = { ...obj };
obj2.a = 100;
console.log( obj1 === obj2 ) // false
console.log( obj1.a ) // 1
const obj1 = { a:1, b:2 };
const obj2 = Object.assign({}, obj1);
obj2.a = 100;
console.log( obj1 === obj2 ) // false
console.log( obj1.a ) // 1
Object.assign()
메서드는 열거할 수 있는 하나 이상의 출처 객체로부터 대상 객체로 속성을 복사할 때 사용하며, 대상 객체를 리턴한다.Object.assign()
메소드를 통해 첫 번째 인자로 빈 { } 객체를, 두 번째 매개변수에 obj1라는 변수에 obj2를 할당했다. 자바스크립트의 메모리 관리는 개발자가 아닌 자바스크립트 엔진이 자동으로 수행한다.
가비지 컬렉터는 자바스크립트 엔진 내부에서 끊임없이 동작하며 모든 객체를 모니터링하여(=메모리 공간 주기적으로 검사) 어떠한 식별자도 참조하지 않는 메모리 공간을 비운다.
가비지 컬렉션 대상의 기준은 '도달 가능한가' 여부이다.
어디서든 접근하거나 사용할 수 있는 값은 '도달 가능한(reachable) 값'으로 분류되어 메모리에서 삭제되지 않는다.
루트에서 참조되는 값이나 스코프 체이닝으로 루트에서 참조될 수 있는 값은 도달 가능한 값이 된다.
가비지 컬렉션의 실행 기반이 되는 알고리즘
메서드는 객체에 제한되어 있는 함수를 의미한다. (프로퍼티 값이 함수일 경우, 일반 함수와 구분하기 위해 메서드라 한다.)
절차 지향적 관점에서 벗어나 독립적인 객체의 집합으로 프로그램을 표현하려는 프로그래밍 패러다임
객체를 먼저 정의하고, 객체간 협력으로 프로그램을 구현한다.
user = {
sayHi: function() {
alert("Hello");
}
};
// 단축 구문
user = {
sayHi() {
alert("Hello");
}
};
다른 언어와 달리 자바스크립트의 this에 바인딩된 값은 런타임(함수 호출 방식에 따라)에 결정된다.
옵셔널 체이닝 ?.
은 좌항의 피연산자가 null 또는 undefined일 경우 undefined를 반환하고 그렇지 않으면 우항의 프로퍼티 참조를 이어간다.
자바스크립트로 존재하지 않는 요소에 접근하여 정보를 가져오려고 할 경우 문제가 발생하는데, 이를 해결하기 위해 && 연산자를 사용했다.
그러나 이렇게 &&로 연결하면 코드가 길어지고 가독성이 떨어진다는 단점이 있었다.
&& 방식
let user = {}; // 주소 정보가 없는 사용자
alert( user && user.address && user.address.street ); // undefined
옵셔널 체이닝
let user = {}; // 주소 정보가 없는 사용자
alert( user?.address?.street ); // undefined
옵셔널 체이닝은 존재하지 않아도 괜찮은 대상에만 사용해야 한다.
필수로 들어가야하는 대상에 값이 할당되지 않았으면 바로 알 수 있어야 하는데 옵셔널 체이닝은 이를 무시하고 다음 연산을 진행해야 하기 때문이다.
obj?.prop – obj가 존재하면 obj.prop을 반환하고, 그렇지 않으면 undefined를 반환
obj?.[prop] – obj가 존재하면 obj[prop]을 반환하고, 그렇지 않으면 undefined를 반환
obj?.method() – obj가 존재하면 obj.method()를 호출하고, 그렇지 않으면 undefined를 반환
https://ko.javascript.info/object
https://poiemaweb.com/js-this