javascript 빌트인 object 이해하기(2-2) - String
javascript 빌트인 object 이해하기(2-1) - String
javascript 빌트인 object 이해하기(1) - Number
javascript 빌트인(Built-in) 이해하기
javascript 연산자(Operator) 이해하기
Prototype과 __proto__ 이해하기(1)
Prototype과 __proto__ 이해하기(2)

이번에 알아볼 자바스크립트의 빌트인 오브젝트는 Object이다.
보통 객체를 object라고 많이 표현하기때문에, String object와 같이 Object object로 표기하기도 해서 헷갈린다.

소문자 object는 객체를 의미하므로 프로퍼티를 가질 수 있다는 의미를 내포하고있고
앞에 대문자로 붙는 Object는 객체의 타입을 의미한다고 생각하면 된다.

빌트인 Object 객체 property

(ES3기준)

Object 객체 생성 : new Object(), Object(),{}

new Object()

new Number(123), new String(123) 의 경우엔, 각각 Number instance 와 String instance를 생성한다.

new Object(123)의 경우는 어떨까? Object instance를 생성할까? 아니다. 파라미터의 데이터 타입에 따라 생성할 인스턴스가 결정된다.

  • 파라미터의 데이터 타입에 따라 생성할 인스턴스 결정(String, Number, Object 등 가능)
  • 파라미터 값이 undefined, null 이면 빈 Object 인스턴스 반환 {}

Object()

  • new Object() 와 같다
  • 파라미터의 데이터 타입에 따라 생성할 인스턴스 결정(String, Number, Object 등 가능)
  • 파라미터 값이 undefined, null 이면 빈 Object 인스턴스 반환 {}

{}

  • 파라미터는 key:value 형식만 가능 (123, "123" 불가능) ( Object 인스턴스만을 반환 가능)
  • 그 외에 new Object()Object()와 동일
  • Object 인스턴스 생성할 땐, new Object()Object()와 동일하므로, 간단하여 자주 활용됨
let newObj1 = new Object(123); // Number 인스턴스 생성
console.log(newObj1); // Number {123}

let newObj2 = Object("123"); // String 인스턴스 생성
console.log(newObj2); // String {123}

let newObj3 = {123}; // SyntaxError : Unexpected number
let newObj3 = {height:123} // 오브젝트 인스턴스 생성

valueOf()

  • Object 인스턴스의 프리미티브 값 반환

hasOwnProperty()

  • 인스턴스에 파라미터 이름이 존재할경우 true, 존재하지 않을시 false 반환 ( 값의 존재여부는 따지지 않음)
  • 자신의 고유 property는 없고, 상속받은 property(__proto__에 존재하는 property)일 경우 false 반환

Prototype과 __proto__이해하기(1)
Prototype과 __proto__이해하기(2)

const obj = {value : undefined}; 
console.log(obj.hasOwnProperty("value")); // 값에 상관없이 value라는 key가 존재하므로 true 반환
console.log(obj.hasOwnProperty("hasOwnProperty")); // Object 의 prototype에 hasOwnProperty가 존재하지만, 자신의 고유 property에는 존재하지 않기때문에 false를 반환

toString()

  • 인스턴스 타입을 문자열로 표시
const point = {book:"책"};
console.log(point.toString()); // [object Object]

ES5 Object

ES5 Object의 특징

Object에 메소드가 추가됨, 대신 이 메소드는 Objectprotype에 정의되어있지 않다. 따라서

  • 상속되지 않고, Object 객체만이 활용함
  • Object.메소드 형식으로 활용

    ❓왜 prototype에 추가하지 않고, 자체 메소드로만 추가했을까?

    ❗prototype 내에 정의되어있다면, 대부분의 객체는 Object를 조상으로 삼기때문에 대부분의 빌트인 object 에 첨부되고, 이러한 빌트인 object를 통해 인스턴스 생성하면, Object의 prototype과 연결이 많이 발생 (Object 객체만이 활용가능한 메소드로 정의할 경우, 연결 부하를 줄일 수 있음)
    Prototype과 __proto__이해하기(1)
    Prototype과 __proto__이해하기(2)

추가된 것

  • method
  • property descriptor

defineProperty()

  • 대상 객체에 프로퍼티 추가 혹은 속성 변경
  • property마다 상태(변경/삭제/열거 가능 여부)를 갖고 있는데, 상태가 가능일때만 처리할 수 있음
  • property 추가할 때, 상태도 결정할 수 있음(default값 : false)
let obj = {};
Object.defineProperty(obj, "book",{
	value : "JS책", // 프로퍼티 value 설정
  	enumerable : false // 프로퍼티 상태 결정
});

for (let name in obj){
	console.log(name + ":" + obj[name]); // undefined(열거불가능))
}

defineProperties()

  • 다수의 프로퍼티를 추가하거나 속성 변경
    • 함수 기능은 defineProperty()와 같음
let obj = {};
Object.defineProperties(obj,{
	soccer : {
      value : "축구", enumerable : true
    },
  	basketball : {
      value : "농구", enumerable : true
    }
});

for (let name in obj){
	console.log(name + ":" + obj[name]); // soccer:축구 basketball:농구(열거가능)
}

getPrototypeOf()

getOwnPropertyNames()

  • 객체의 property 이름을 배열로 반환
  • 열거 가능 여부는 체크하지 않음 (enumerablefalse여도 반환됨)
  • 객체 자신이 만든 property가 대상(상속받은건 제외)

keys()

  • 객체의 property 중 열거가능한 property 이름을 배열로 반환
  • 객체 자신이 만든 property가 대상(상속받은건 제외)

property descriptor

property descriptor : property의 속성 이름과 속성 값을 정의

위의 예시에선, 프로퍼티의 값(value)속성에 값을 정의하고,enumerable 속성에 값을 할당하는 것이 보여졌다.
이처럼, ES5엔 value뿐만 아니라 다양한 property descriptor 가 새로이 정의되었다.

descriptor type 분류

  • data property descriptor : value, writable
  • access property descriptor : get, set
  • 공용 property descriptor : enumerable, configurable

descriptor type 인식 기준

  • data 와 access property descriptor는 함께 작성할 수 없다. (이후 좀 더 자세한 설명...)

❓ES5에서 상태를 결정할 수 있게 한 이유는?

❗오픈소스로 코드를 공개하게 될때, ES5전까지는 일부는 코드를 보고서 자신의 데이터에 접목?시킬 수도 있었다. 따라서, 이러한 속성을 활용하여 데이터를 보호하는 차원이 주된 이유 중 하나이다.

value

  • property의 값 ( default : undefined )
  • get/set 속성과 같이 작성 불가

writable

  • property value 속성값 변경 가능(true)/불가능(false(default))
  • false일 경우, 변경 시도시 에러가 발생하지 않지만, 값이 변경되지 않음
  • get/set 속성과 같이 작성 불가

enumerable

  • for...in 으로 열거 가능(true)/불가능(false(default))

configurable

  • property 삭제 가능(true)/불가능(false(default))
  • true : value 이외 속성 변경 가능 / 프로퍼티 삭제 가능
  • false : 프로퍼티 삭제 불가, value이외 속성 변경 불가
let obj ={};
Object.defineProperty(obj,"book",{
	value :"JS책",
    writable : false, // value 변경불가
    configurable : true // value이외 속성값 변경 가능 / 프로퍼티 삭제 가능
});
obj.book = "goggling책";
console.log(obj.book); // JS책(value 변경안됨)
delete obj.book; // 프로퍼티 삭제 가능
console.log(obj.book); //undefined

get

  • default : undefined
  • 객체.프로퍼티 를 호출할 때, value 속성이 정의되지 않았을 경우, get 함수의 리턴값 반환
  • data type property descripter와 동시 사용 불가 (value와 함께 작성시 : 누굴 반환해야하지? 되므로 동시 작성 불가 / writable과 함께 작성시 : 함수의 value값을 변경 가능/불가능을 설정하는 descriptor인데 value 값이 get과 존재할 수 없으므로 동시 작성 불가)
  • 객체.프로퍼티.get() 처럼 함수로 호출하면 에러 발생

set

  • default : undefined
  • 객체.프로퍼티 = value 를 작성할 때, value 속성이 정의되지 않았을 경우, set 함수에 해당 value가 parameter로 들어가고, 리턴값을 프로퍼티에 할당함
  • data type property descripter와 동시 사용 불가 (value와 함께 작성시 : 누구의 값으로 설정하지? 되므로 동시 작성 불가 / writable과 함께 작성시 : 함수의 value값을 변경 가능/불가능을 설정하는 descriptor인데 value 값을 변경할지, set의 return 값을 변경할지 알수없으므로 동시 작성 불가)
  • 객체.프로퍼티.set() 처럼 함수로 호출하면 에러 발생
let obj = {}
Object.defineProperty(obj, "book", {
	set : function(param){
		obj.title = param.toUpperCase(); // parameter를 받아 대문자로 바꿔줌
	},
	get : function(){
		return obj.title;
	}
});

obj.book = "jsbook"
console.log(obj.book); //JSBOOK

property descriptor 메소드

getOwnPropertyDescriptor()

  • property descriptor의 속성과 값 반환
    Object.getOwnPropertyDescriptor(객체이름, property;

preventExtensions()

재해석 : 객체 확장 금지! (객체 몸집을 그만불려라..)

  • 객체에 property 추가 금지 설정
  • property 삭제, 변경은 가능
  • 추가 금지로 설정한 경우, 추가 가능으로 변경 불가
    Object.preventExtensions(객체이름)

isExtensible()

  • 객체에 property 추가 금지 여부 반환[true, false]

seal()

재해석 : 객체 밀봉! (객체의 형태를 건들 수 없습니다. 건드리려면 밀봉을 풀어주세요)

  • 객체에 property 추가 및 삭제 금지 설정 (시도시,error는 나지 않으나, 변경안됨)
  • 객체의 property의 모든 속성이 설정 불가능(non-figurable) 해짐 (시도시,error는 나지 않으나, 변경안됨)
  • 속성값은 변경 가능 ( 속성값의 변경을 제외한 어떤 변경도 적용되지 않음 )

조금 헷갈리니깐...
다시 재해석 : 객체 밀봉! 외부에서 만지작거리는건 안되고(ex. defineProperty와 같은 형태)
내부에서 속성값 변경은 가능(ex. 객체.프로퍼티 로 접근하여 변경)

isSealed()

  • 객체의 seal 여부 반환 [true,false]

freeze()

  • 객체 동결! 불변함
  • 동결이지만, 얕은 동결(shallow freeze)이라고 부른다. 왤까? 아래 질문을 생각해 볼 수 있다.

    ❓ 객체의 프로퍼티 값이 객체라면? 객체의 객체(inner 객체)도 과연 동결이 될까요? 아니요.
    ❓ * inner 객체를 포함한 객체의 객체의 객체의 객체.... 를 모두 동결 시키려면 어떻게 해야할까요?

    ❗이런 것을 수행하기 위한, deepFreeze()라는 개념도 존재한다.

Object.seal()과의 비교 : Object.seal()을 사용해 봉인된 객체는 존재하는 속성을 변경할 수 있습니다. Object.freeze()로 동결된 객체에서는 존재하는 속성이 불변입니다.

isFrozen()

  • 객체의 freeze 여부 반환 [true,false]

이걸 다 외우는 건 있을 수 없는 일이고, 개념과 동작원리를 알고 나중에 필요할 때 서치하여 활용할 수 있는정도만 알아두면 충분할 것이다.


내용에 오류가 있으면 알려주시면 감사합니다!

0개의 댓글