Search
Duplicate

Object 오브젝트(ES5 기준)

1. ES5 Object 특징, ES5 Object함수, 프로퍼티 디스크립터

ES5 Object특징

ES5 Object에 함수가 추가됨
메소드는 하나도 없습니다.
빌트인 Object의 모든 메소드는 대부분의 빌트인 오브젝트에 첨부되었고, 빌트인으로 오브젝트를 생성하기에 연결이 많이 발생합니다.
함수는 첨부되지 않기에 연결 부하를 줄일 수 있습니다.

ES5 Object 함수

defineProperty() : 프로퍼티 추가, 프로퍼티 속성 변경
defineProperties(): 다수의 프로퍼티 추가, 속성 변경
getPrototypeOf(): prototype에 연결된 프로퍼티 반환
getOwnPropertyNames(): 프로퍼티 이름을 배열로 반환
keys(): 열거 가능 프로퍼티 이름 반환
getOwnPropertyDescriptor(): 디스크립터 속성 반환
preventExtensions(): 프로퍼티 추가 금지 설정
isExensible(): 프로퍼티 추가 금지 여부 반환
seal(): 프로퍼티 추가, 삭제 금지 설정
isSealed(): 프로퍼티 추가, 삭제 금지 여부 반환
freeze(): 프로퍼티 추가, 삭제/ 변경 금지 설정
isFrozen(): 프로퍼티 추가, 삭제/변경 금지 여부 반환=

프로퍼티 디스크립터

value : [[value]], 설정할 값
writable : [[Writable]], 값 변경 가능 여부
get : [[Get]], 값 반환 프로퍼티 함수
set : [[Set]], 값 설정 프로퍼티 함수
enumerable : [[Enumerable]], 프로퍼티 열거 가능 여부
configurable : [[Configurable]], 프로퍼티 삭제 가능 여부

2. Object에 프로퍼티 추가

defineProperty()

Object.defineProperty(obj, prop, descriptor)
매개변수
obj : 속성을 정의할 객체
prop : 새로 정의하거나 수정하려는 속성의 이름 또는 Symbol
descriptor : 새로 정의하거나 수정하려는 속성을 기술하는 객체.
프로퍼티마다 상태를 가지고 있으며 상태란 변경,삭제,열거 가능여부를 말합니다.
var obj = {}; Object.defineProperty(obj, "book", { //---(1) value: "JS북", enumerable: true }); console.log(obj); /* {book: "JS북"} */
JavaScript
복사
⇒ (1): defineProperty라는 함수로 Object에 프로퍼티를 추가합니다. 위 코드에서는 첫번째 파라미터인 obj에 두 번째 파라미터의 이름으로 프로퍼티를 만들어서 세 번째 파라미터의 옵션으로 값과 열거여부등을 설정합니다. 위 코드에서는 book이라는 프로퍼티에 JS북 이라는 값을 설정하고 열거가 가능하게 설정했습니다.

defineProperties()

다수의 프로퍼티를 추가하거나 속성을 변경합니다.
함수 긴으은 defineProperty()와 같습니다.
var obj = {}; Object.defineProperties(obj, { soccer: { value: "축구", enumerable: true }, basketball: { value: "농구", enumerable: false // ---(1) } }); for(var name in obj){ console.log(name + ":" + obj[name]); }; /* soccer:축구 */
JavaScript
복사
⇒ (1): 열거 여부를 false로하면 for-in 이나 keys()같은 메서드에서 열거할 때 참조되지 않습니다.

3. 프로퍼티 디스크립터, value/writable/enumerable/configurable 속성

프로퍼티 디스크립터(Descriptor)
프로퍼티의 속성 이름과 속성 값을 정의합니다.
디스크립터 타입 분류
데이터 프로퍼티 디스크립터
액세스(Access) 프로퍼티 디스크립터
공용 프로퍼티 디스크립터
디스크립터 타입에 속한 속성만 같이 사용할 수 있습니다.
데이터 타입과 액세스 타입은 같이 사용할 수 없습니다.

디스크립터 타입 인식 기준

먼저 value 또는 writable 작성 확인
작성되어 있는 경우
데이터 프로퍼티 디스크립터 타입으로 인식
작성되어 있지 않은 경우
액세스 프로퍼티 디스크립터 타입으로 인식
데이터와 액세스 프로퍼티 디스크립터를 함께 작성할 수 없기에 구분이 가능합니다.

value 속성

프로퍼티 값
{value: "JS"}형태로 작성
for~in 에서 "JS북"이 프로퍼티 값이 됩니다.
value 속성을 get/set속성과 같이 작성 불가합니다.
var obj = {}; Object.defineProperty(obj, "book", { value:"JS북", enumerable: true }); for(var name in obj){ console.log(name); console.log(obj[name]); } /* value와 get/set 작성 혼용 불가*/ var obj = {}; Object.defineProperty(obj, "book", { value: "JS북", get: function(){} //---(1) });
JavaScript
복사
⇒ (1): get을 혼용해서 쓰게되면 아래와같은 에러메세지가 출력됩니다.

writable 속성

프로퍼티 값 변경 가능, 불가
writable: true
프로퍼티 변경이 가능해집니다.
writable: false
디폴트 값: false
프로퍼티 변경이 불가능해지고 에러가 발생하지 않지만 값이 변경되지 않습니다.
var obj = {}; Object.defineProperty(obj, "book", { value: "JS책", writable: true }); obj.book = "변경 가능"; console.log(obj.book);//변경 가능 //writable false Object.defineProperty(obj, "book", { value: "JS책", writable: false }); obj.book = "변경 가능"; console.log(obj.book);//JS책
JavaScript
복사

enumerable 속성

for~in 으로 열거 가능 여부
enumerable: true
프로퍼티 열거 가능
enumerable: false
디폴트 값: false
프로퍼티 열거 불가
var obj = {}; Object.defineProperty(obj, "book", { value: "JS책", enumerable: true }); for(var name in obj){ console.log(name, ":"+obj[name]); }; //book: JS책 //enemerable false var obj = {}; Object.defineProperty(obj, "book", { value: "JS책", enumerable: false }); for(var name in obj){ console.log(name, ":"+obj[name]); }; //결과없음
JavaScript
복사

configurable 속성

프로퍼티 삭제 가능 불가
configurable: true
프로퍼티 삭제 가능
value 이외 속성 변경 가능
var obj = {}; Object.defineProperty(obj, "book", { value: "JS책", configurable: true }); delete obj.book; console.log(obj.book);// undefined
JavaScript
복사
configurable: false
디폴트 값: false
프로퍼티 삭제 불가
value이외 속성 변경 불가
var obj = {}; Object.defineProperty(obj, "book", { value: "JS책", configurable: false }); delete obj.book; console.log(obj.book);// JS책
JavaScript
복사

4. getter와 setter, get속성, set속성

get 속성

getter
OOP용어
var result = obj. book; 코드를 만나면
var obj = {}; Object.defineProperty(obj, "book", { get: function(){ return "JS책";} }); var result = obj.book; console.log(result);// JS책
JavaScript
복사
obj.book의 get함수가 호출되며 get함수에서 JS책 을 result변수에 할당합니다.
obj.book.get()처럼 함수로 호출하면 에러가 발생합니다.

set속성

setter
OOP용어
obj.book = "JS책"; 코드를 만나면
var obj = {}, data = {} Object.defineProperty(obj, "book", { set: function(param){ data.title = param}, get: function(){return data.title;} }); obj.book = "JS책"; console.log(obj.book);// JS책
JavaScript
복사
obj.book의 set함수를 호출하며 JS책 을 파라미터 값으로 넘겨줍니다.
data의 title 프로퍼티에 "JS책"을 설정
obj.book; 코드를 만나면
obj.book의 get함수가 호출되며 get함수에서 data.title값을 반환합니다.
ES6에서 getter/setter문법이 더 간편해져서 ES6에서는 다른 방법을 사용합니다.

5. 프로퍼티 추출

getPrototypeOf()

파라미터의 prototype에 연결된 프로퍼티 반환
function Book(point){ this.point = point; }; Book.prototype.getPoint = function(){}; Book.prototype.setPoint = function(){}; var obj = new Book(100); var result = Object.getPrototypeOf(obj); for(var key in result){ console.log(key + ":" + result[key]); }; /* getPoint:function(){} setPoint:function(){} */
JavaScript
복사
setPrototypeOf()는 ES5가아닌 ES6스펙에 있습니다.

getOwnPropertyNames()

오브젝트의 프로퍼티 이름을 배열로 반환합니다.
열거 가능 여부를 체크하지 않습니다.
자신이 만든 프로퍼티가 대상
다른 오브젝트에서 받은 프로퍼티는 제외합니다.
var obj = {}; Object.defineProperties(obj, { book: {value: "책"}, point: {value:123} }); var names = Object.getOwnPropertyNames(obj); for(var k = 0; k < names.length; k++){ console.log(names[k]);//---(1) }; /* book point */
JavaScript
복사
⇒(1): defineProperties에서 enumerable의 기본값은 false입니다. 즉 따로 설정해주지 않으면 열거할 수 없게 되어있지만, getOwnPropertyNames() 는 해당 속성을 체크하지 않고 진행합니다.

keys()

열거 가능 프로퍼티 이름 반환
enumerable이 true인 경우
var obj = {}; Object.defineProperties(obj, { book: {value: "책", enumerable: true}, point: {value:123} }); var names = Object.keys(obj); for(var k = 0; k < names.length; k++){ console.log(names[k]);//---(1) }; /* book */
JavaScript
복사
⇒ enumerable이 true로 설정된 book만 출력됩니다.

6. 프로퍼티 디스크립터 함수

getOwnPropertyDescriptor()

프로퍼티 디스크립터의 속성 이름, 값을 반환합니다.
다른 오브젝트에서 받은 프로퍼티는 제외합니다.
var obj = {}; Object.defineProperty(obj, "book", { value: "책", enumerable: true, writable: true }); var desc = Object.getOwnPropertyDescriptor(obj, "book"); for(var key in desc){ console.log(key + ":" + desc[key]); }; /* value:책 writable:true enumerable:true configurable:false */
JavaScript
복사

preventExtensions()

오브젝트에 프로퍼티 추가 금지 설정
프로퍼티 삭제, 변경은 가능
추가 금지를 설정한 후에는 추가 가능으로 변경 불가합니다.
var obj = {}; Object.preventExtensions(obj); try{ Object.defineProperty(obj, "book", { value: "책", }); } catch(e){ console.log("추가 불가"); }; //추가 불가
JavaScript
복사

isExtensible()

오브젝트에 프로퍼티 추가 금지 여부 반환
true: 추가 가능, false: 추가 불가
var obj = {}; Object.defineProperty(obj, "book", { value: "책", }); console.log(Object.isExtensible(obj));//true Object.preventExtensions(obj); console.log(Object.isExtensible(obj));//false
JavaScript
복사

seal()

오브젝트에 프로퍼티 추가, 삭제 금지 설정
추가 금지는 오브젝트 단위로 설정하고 삭제금지는 프로퍼티 단위로 설정합니다.
추가 금지를 하더라도 변경은 가능합니다.
var obj = {}; Object.defineProperty(obj, "book", { value: "책",writable: true }); Object.seal(obj); try{ Object.defineProperty(obj, "sports", { value: "스포츠" }); } catch(e){ console.log("추가 불가"); };
JavaScript
복사

isSealed()

오브젝트에 프로퍼티 추가, 삭제 금지 여부를 반환합니다.
true: 불가, false: 가능
var obj = {}; Object.defineProperty(obj, "book", { value: "책",writable: true }); console.log(Object.isSealed(obj));//false Object.seal(obj); console.log(Object.isSealed(obj));//true
JavaScript
복사

freeze()

오브젝트에 프로퍼티 추가, 삭제, 변경 금지 설정
var obj = {}; Object.defineProperty(obj, "book", { value: "책",writable: true }); Object.freeze(obj); try{ Object.defineProperty(obj, "book", { value: "포인트" }); } catch(e){ console.log("변경 불가"); }; console.log(obj.book); /* 변경 불가 JS책 */
JavaScript
복사

isFrozen()

오브젝트에 프로퍼티 추가, 삭제, 변경 금지 여부를 반환합니다.
true: 불가, false: 가능
var obj = {}; Object.defineProperty(obj, "book", { value: "책",writable: true }); console.log(Object.isFrozen(obj));//false Object.freeze(obj); console.log(Object.isFrozen(obj));//true
JavaScript
복사