자바스크립트 (객체)

이종경·2024년 4월 11일
0

자바스크립트

목록 보기
2/11
post-thumbnail

생각보다 내가 모르는건 많았다.

1. this ?

this에 연결된 프로퍼티와 메소드는 public이다

function Person(name, gender) {
  var married = true;         // private
  this.name = name;           // public
  this.gender = gender;       // public
  this.sayHello = function(){ // public
    console.log('Hi! My name is ' + this.name);
  };
}
var person = new Person('Lee', 'male'); // 생성자 함수 호출
console.log(person); // Person { name: 'Lee', gender: 'male', sayHello: [Function] }
console.log(person.gender);  // 'male'
console.log(person.married); // undefined

this에 연결(바인딩)되어 있는 프로퍼티와 메소드는 public(외부에서 참조 가능)한 반면, 일반 변수는 private(외부에서 참조 불가능)하다.

2. for-in 반복문을 이용한 객체 순회

for-in 문은 객체의 문자열 키(key)를 순회하기 위한 문법이다.
물론 배열에도 사용가능하지만, 순서가 보장되지 않고 배열 요소들만 순회하는 것이 아니기 때문에 배열을 사용할 경우for-of반복문을 사용하는 것이 권장된다.

var person = {
  'name': 'Lee',
  gender: 'male'
};
// prop에 객체의 프로퍼티 이름이 반환된다. 단, 순서는 보장되지 않는다.
for (var prop in person) {
  console.log(prop + ': ' + person[prop]);
}
/*
name: Lee
gender: male
*/
var array = ['one', 'two'];
// 배열의 경우 인덱스가 반환된다
for (var index in array) {
  console.log(index + ': ' + array[index]);
}
/*
0: one
1: two
*/

3. Object.assign을 이용한 객체의 얕은복사

Object.assign은 타킷 객체소스 객체의 프로퍼티를 복사한다.
이때 소스 객체의 프로퍼티와 동일한 프로퍼티를 가진 타켓 객체의 프로퍼티들은 소스 객체의 프로퍼티로 덮어쓰기된다. 리턴값으로 타킷 객체를 반환한다.

Object.assign(target, ...sources)

아래의 예시를 통해 살펴보자.

// Merge
const o1 = { a: 1 };
const o2 = { b: 2 };
const o3 = { c: 3 };

const merge1 = Object.assign(o1, o2, o3);

console.log(merge1); // { a: 1, b: 2, c: 3 }
console.log(o1);     // { a: 1, b: 2, c: 3 }, 타겟 객체(o1)가 변경된다!

하지만 객체 내부에 또 다른 객체가 있을 경우 얕은 복사가 된다. 즉, 객체 내부의 또 다른 객체가 있을 경우 그 값을 변경하면 기존의 객체와 복사된 객체 모두 변경된다.

const user1 = {
  name: 'Lee',
  address: {
    city: 'Seoul'
  }
};

// 새로운 빈 객체에 user1을 copy한다.
const user2 = Object.assign({}, user1);
// user1과 user2는 참조값이 다르다.
console.log(user1 === user2); // false

user2.name = 'Kim';
console.log(user1.name); // Lee
console.log(user2.name); // Kim

// 객체 내부의 객체(Nested Object)는 Shallow copy된다.
console.log(user1.address === user2.address); // true

user1.address.city = 'Busan';
console.log(user1.address.city); // Busan
console.log(user2.address.city); // Busan

4. Object.freeze를 이용한 불변 객체 생성

Object.freeze()를 사용하여 불변(immutable) 객체로 만들수 있지만, 객체 내부의 객체는 변경가능하다.

const user1 = {
  name: 'Lee',
  address: {
    city: 'Seoul'
  }
};

// Object.assign은 완전한 deep copy를 지원하지 않는다.
const user2 = Object.assign({}, user1, {name: 'Kim'});

console.log(user1.name); // Lee
console.log(user2.name); // Kim

Object.freeze(user1);

user1.name = 'Kim'; // 무시된다!

console.log(user1); // { name: 'Lee', address: { city: 'Seoul' } }

console.log(Object.isFrozen(user1)); // true

user1.address.city = 'Busan';
console.log(user1); // { name: 'Lee', address: { city: 'Busan' } }

따라서 내부 객체를 변경 불가능하게 만들려면 Deep freeze를 해야 한다.

function deepFreeze(obj) {
  const props = Object.getOwnPropertyNames(obj); // 객체의 모든 프로퍼티를 배열로 반환

  props.forEach((name) => {
    const prop = obj[name]; // 객체의 프로퍼티를 변수에 저장
    /* 
    객체의 프로퍼티가 객체이고 Null이 아닌 경우 해당 프로퍼티에 deepFreeze를 다시 실행
    */
    if(typeof prop === 'object' && prop !== null) { 
      deepFreeze(prop);
    }
  });
  return Object.freeze(obj); // 객체를 불변으로 설정
}

5. BOM과 DOM

BOM (Browser Object Model)

BOM은 브라우저 탭 또는 브라우저 창의 모델을 생성한다. 최상위 객체는 window 객체로 현재 브라우저 창 또는 탭을 표현하는 객체이다. 또한 이 객체의 자식 객체 들은 브라우저의 다른 기능들을 표현한다. 이 객체들은 Standard Built-in Objects가 구성된 후에 구성된다.
BOM

DOM (Document Object Model)

DOM은 현재 웹페이지의 모델을 생성한다. 최상위 객체는 document 객체로 전체 문서를 표현한다. 또한 이 객체의 자식 객체들은 문서의 다른 요소들을 표현한다. 이 객체들은 Standard Built-in Objects가 구성된 후에 구성된다.
DOM

객체편을 마무리하며

그래프

참고
자바스크립트의 기본
일급 객체(first-class object) 란?

profile
작은 성취들이 모여 큰 결과를 만든다고 믿으며, 꾸준함을 바탕으로 개발 역량을 키워가고 있습니다

0개의 댓글