-
[JS] 객체에 관하여programing/Language 2020. 1. 1. 23:29
안녕하세요, Einere입니다.
(ADblock을 꺼주시면 감사하겠습니다.)
해당 포스트는 러닝 자바스크립트를 읽고 간단하게 정리한 포스트입니다.
배열과 객체
배열
배열은 객체의 하위집합입니다.
배열은 인덱스(0, 1, 2, ...)를 프로퍼티로 가지는 특별한 객체입니다.
배열의 요소는 순서를 가집니다.
객체
객체는 문자열이나 심볼로 된 프로퍼티를 가집니다.
객체의 프로퍼티는 키와 값으로 구성되어 있으며, 각 키는 값을 가집니다.
객체의 프로퍼티는 순서를 가지지 않으며, 보장하지 않습니다. ex) for in
for in문에 키가 심볼인 프로퍼티는 포함되지 않습니다.
const Car = function() { const carProps = new WeakMap(); class Car { constructor(make, model) { this.make = make; this.model = model; this._userGears = ["P", "N", "R", "D"]; carProps.set(this, { userGear: this._userGears[0] }); } get userGear() { return carProps.get(this).userGear; } set userGear(value) { if (this._userGears.indexOf(value) < 0) throw new Error(`invalid gear : ${value}`); carProps.get(this).userGear = value; } shift(gear) { this.userGear = gear; } } return Car; }; const car = Car(); const car1 = new car(); console.log(car1.userGear); // "P" car1.shift('N'); console.log(car1.userGear); // "N"
JS에는 Java와 같이 프로퍼티나 메소드에 접근할 수 있는 범위(public, private, ...)를 지정하는 기능이 없습니다. 그래서 보통 private 속성이나 메소드는 식별자(변수명)앞에 언더바(_)를 붙입니다. 혹은, WeapMap인스턴스와 클로저를 이용하여 보호할 수 있습니다.
hasOwnProperty
이 메소드는 객체가 특정 프로퍼티를 자기만의 직접적인 프로퍼티로서 소유하고 있는지를 판단하는데 사용된다.
in 연산과는 다르게, 이 메소드는 객체의 프로토타입 체인을 확인하지는 않는다.해당 객체의 특정 프로퍼티가 정말로 자신의 것인지 판단하는 함수입니다. 즉, 상속받은(prototype chain) 프로퍼티인지 아닌지 판단할 수 있습니다.
믹스인
다중상속이 필요한 경우에 사용가능한 기법입니다.
만약 특정 Car 인스턴스는 자동차이면서 보험에 가입할 수 있습니다.
class InsurancePolicy{} function makeInsurable(obj) { obj.addInsurancePolicy = function(policy) { this.insurancePolicy = policy; }; obj.getInsurancePolicy = function() { return this.insurancePolicy; }; obj.isInsured = function() { return !!this.insurancePolicy; }; }
위와 같은 기능이 필요하다고 한다면, 다음과 같이 믹스인을 사용할 수 있습니다.
const car1 = new Car(); makeInsurable(car1); car1.addInsurancePolicy(new InsurancePolicy());
위 코드는 모든 인스턴스에 대해 makeInsurable()을 호출해줘야 하기 때문에 불편합니다. 따라서 다음과 같이 개선할 수 있습니다.
makeInsurable(Car.prototype); const car1 = new Car(); car1.addInsurancePolicy(new InsurancePolicy());
중복상속으로 인한 메소드 충돌은 Symbol을 이용해 해결할 수 있습니다.
class InsurancePolicy {} const ADD_POLICY = Symbol(); const GET_POLICY = Symbol(); const IS_INSURED = Symbol(); const _POLICY = Symbol(); function makeInsurable(obj) { obj[ADD_POLICY] = function(policy) { this._POLICY = policy; }; obj[GET_POLICY] = function() { return this._POLICY; }; obj[IS_INSURED] = function() { return !!this._POLICY; }; }
그러나 믹스인을 사용한다면, instanceof를 이용해서 믹스인으로 상속한 객체임을 판단할 수 없습니다. (위 예시에서는 instanceof로 car1이 addInsurancePolicy()를 포함한 메소드를 상속했는지 알 수 없습니다.)
비구조화 할당 꿀팁
const obj = {a:1, b:2, c:3}; let a, b, c = null; {a, b, c} = obj; // error ({a, b, c} = obj); // work
변수를 미리 선언해둔 후, 나중에 비구조화 할당을 하고 싶은 경우가 있습니다.
try catch문 내부에서 할당을 해야 하는 등 스코프 문제가 대부분이죠.
없다면 JS엔진은 해당 코드를 블럭으로 인식하기 때문에, 괄호를 사용하면 제대로 인식해서 비구조화 할당이 됩니다.
참고
이선 브라운, 『러닝 자바스크립트, ES6로 제대로 입문하는 모던 자바스크립트 웹 개발』, 한빛미디어(2017).
'programing > Language' 카테고리의 다른 글
[TS] TypeScript 기초 - 2 (0) 2020.01.25 [TS] TypeScript 기초 - 1 (0) 2020.01.24 [Functional] 고차 함수 (0) 2019.12.29 [JS] 웹 프론트 쿠키 파서 (0) 2019.11.18 [React] react에서 fontawesome사용하는 방법 (0) 2019.10.23 댓글