2oneweek.dev

25. JS에서 Object(객체)란?

    Tags

  • JavaScript
25. JS에서 Object(객체)란? thumbnail

객체란

객체의 정의 방식

  1. 선언적(리터럴) 형식의 정의 var obj = { name: "한주", age: 27, };
  2. 생성자 형식의 정의 var obj = new Object(); obj.name = "한주"; obj.age = 27;
  • 두 정의 방식은 똑같은 결과를 반환한다. 다만 차이점이라고는 생성자 형식은 한 번에 하나의 프로퍼티만 설정이 가능하다는 것이다. 반면 리터럴 방식은 한 번에 객체를 통으로 만들 수 있음


내장 객체와 원시 타입

단순 원시 타입

  • null
  • undefined
  • boolean
  • number
  • string
  • object
  • symbol

자바스크립트에는 7개의 원시타입(primitive)이 존재한다. 이러한 단순 원시 타입은 객체가 아니다. 따라서 "자바스크립트는 모든 것이 객체다." 라는 말은 사실이 아니다.

  • typeof null === object //=> true인 것은 자바스크립트의 오랜 버그다. "단순" 원시타입은 객체가 아니다.
  • 복합 원시 타입이라는 것이 존재하는데, 이것은 객체의 하위 타입이다. 더 공부해봐야 한다.

내장 객체

내장 객체라는 객체 하위 타입이 있다.

  • String
  • Number
  • Boolean
  • Function
  • Array
  • Date
  • RegExp
  • Error 내장 객체는 마치 클래스처럼 느껴진다. 그러나 이것들은 JS의 내장 함수(함수는 일급 객체)로 생성자로 쓰인다. 즉 이것들은 new키워드와 함께 각각 하위 객체를 생성하는 생성자들이다.

단순 원시 타입은 객체가 아니다.

var primitiveStr = "단순 원시 문자열"; var objectStr = new String("문자열 객체"); console.log(typeof primitiveStr); //=> string console.log(typeof objectStr); //=> object console.log(primitiveStr instanceof String); //=> false console.log(objectStr instanceof String); //=> true
  • "단순 원시 문자열"이라는 원시 값은 객체가 아니라 원시 리터럴이며 불변값이다.
  • 따라서 원래는 String의 prototype에 연결된 메소드를 사용할 수가 없다.(인스턴스가 아니므로)
  • 그러나 JS 엔진은 상황에 맞게, 문자열 원시 값을 String 객체로 자동 강제 변환해주기 때문에, 우리가 편하게 리터럴 방식을 사용할 수 있는 것이다.



객체의 불변성

우리는 재할당을 const로 방지하려고 한다. 그러나 객체에서 const는 얕은 불변성만을 제공한다.

const obj = { name: "이한주", age: 27, }; // obj = {} !!Error obj.name = "한주";
  • const로 obj 변수 자체에 다른 것이 재할당 되는 것을 막을 수는 있다.
  • 그러나 프로퍼티가 변경되는 것은 막을 수 없다. 그래서 const는 객체에게 얕은 불변성만을 제공해준다는 것이다.


프로퍼티를 불변하게

Object.defineProperties 써서 원하는 프로퍼티를 불변하게 만들 수 있다.

  • writable : false
    • true일 경우 이 속성에 설정된 값을 할당 연산자로 수정할 수 있다. 기본값은 false이다.
  • configurable : false
    • true일 경우 이 속성 서술자의 형태를 변경하거나(defineProperties를 통해 재정의하는 것), 속성을 해당 객체에서 삭제할 수 있다. 기본값은 false이다.
var obj = {}; Object.defineProperties(obj, { name: { value: "이한주", writable: false, configurable: false, }, age: { value: 27, writable: true, }, }); obj.name = "asdasd"; //error가 나진 않음 console.log(obj.name); //변경되지 않음 obj.age = 9999; console.log(obj.age); //변경됨

확장 금지

  • Object.preventExtensions를 사용하면, 해당 object의 프로퍼티 확장이 불가능해진다.
var obj = { name: "이한주", }; Object.preventExtensions(obj); obj.age = 27; console.log(obj.age); //=> undefined

Object.seal() 과 Object.freeze

Object.seal()

말 그대로 객체를 "봉인"시킨다. seal()은 다음과 같은 작업을 한다.

  1. Object.preventExtentions()
    • 따라서, 새로운 프로퍼티 추가가 불가능해진다.
  2. configurable = false 모든 프로퍼티에 configurable을 false로 만든다.
    • 따라서, 프로퍼티의 값을 변경하는 것은 얼마든지 가능하다. 대신 definedProperties를 통해, 프로퍼티의 성격을 재정의 하는것은 불가능해진다.

Object.freeze()

말 그대로 객체를 "동결"시킨다. 객체를 확장할 수도 없고, 프로퍼티의 값을 변경시킬 수도 없다. 반면, 객체를 재할당 하는 것은 가능하다. 재할당의 방지는 const가 해주는 것이기 때문이다.

var obj = { name: "한주", age: 27, }; obj.a = 123; obj.name = "asdasdasd"; console.log(obj); // 그대로다. obj = {}; console.log(obj); // {}

freeze 주의할 점

freeze 내부에 객체가 존재할 수 있다. freeze를 하게되면 객체 내부에 참조하고 있는 객체들을 모두 "동결"시키기 때문에(Deep freeze), 작성한 코드가 동작 안할 수 있으므로 주의하자.

Written by@2-one-week
현재 블로그 개발 중

GitHubLinkedIn