HTML5와 함께 출현한 자바스크립트 표준안을 ECMAScript 5 라고 부릅니다. ECMAScript 5는 기존의 자바스크립트에서 특히 객체 관련 부분을 많이 보완했습니다. 참고로 ECMAScript 5는 인터넷 익스플로러 9이상이나 그 외 브라우저에서만 작동합니다.
객체 속성 추가
- Object.defineProperty(객체명, 속성명, {옵션}) : 객체에 속성을 하나 추가
- Object.defineProperties(객체명, { 속성명: {옵션} } ) : 객체에 속성을 여러 개 추가
Object.defineProperty( )
var obj = {}; Object.defineProperty(obj, 'name', { value: 'ECMAScript', writable: false, configurable: false, enumerable: false });
위의 코드는 obj 객체에 name이라는 속성을 만들고 그 값을 'ECMAScript'로 설정합니다. Object.defineProperty()의 세 번째 인자에 옵션을 줄 수 있는데 각 옵션은 아래와 같습니다.
- value: 속성 값
- writable: 속성 값을 변경할 수 있는지의 여부(true/false)
- configurable: 속성의 옵션값을 변경할 수 있는지의 여부(true/false)
- enumerable: fon in 반복문으로 검사할 수 있는지의 여부(true/false)
- get: 게터 함수. value 옵션과 함께 사용할 수 없습니다.
- set: 세터 함수. value 옵션과 함께 사용할 수 없습니다.
- 위의 모든 옵션의 기본 값은 false 또는 undefined 입니다.
writable이 true이면 obj.name = 'aaa'; 와 같은 값을 변경하는 코드를 사용할 수 있습니다.
configurable이 true이면 Object.defineProperty(obj, 'name' , { writable: true });와 같이 사용하여 옵션 값을 변경할 수 있습니다.
enumerable이 true이면 for in 반복문을 사용하여 name 속성을 출력할 수 있습니다.
get, set 옵션은 value 옵션과 함께 사용할 수 없어서 아래의 별도 소스 코드를 준비했습니다.
var obj = {}; Object.defineProperty(obj, 'name', { // value 옵션을 함께 사용할 수 없습니다! get: function() { return value; }, set: function(newValue) { value = newValue; } }); obj.name = 'ECMAScript'; // set 호출 alert(obj.name); // get 호출
위처럼 get과 set을 통해 게터와 세터를 만들어 주고 obj.name 과 같이 속성 값에 접근하면 자동적으로 게터와 세터 함수를 통해 조작됩니다. 실제로 set 함수에 alert창을 띄우는 코드를 삽입하면 obj.name = 'ECMAScript'; 부분에서 실제로 alert 창이 띄워집니다.
Object.defineProperties( )
var obj = {}; Object.defineProperties(obj, { name: { value: 'ECMAScript' }, type: { value: 'Programming Language' } }); alert(obj.name); alert(obj.type);
Object.defineProperties()는 객체의 속성을 여러 개 지정할 수 있습니다. Object.defineProperty와 개수만 다를 뿐 사용 방법은 비슷합니다. 위의 코드는 객체 obj에 속성 name과 type을 지정한 예제입니다.
객체 생성(상속)
Object.create( )
- Object.create(객체명, { 속성명: {옵션} } ) : 첫 번째 매개 변수로 받은 객체에 두 번째 매개 변수로 받은 속성을 추가하여 새로운 객체를 리턴합니다. 이 때 두 번째 매개 변수는 Object.defineProperties와 문법이 같습니다.
// 첫 번째 매개변수에 빈 객체를 전달 함으로써 // 완전히 새로운 객체를 만드는 효과를 볼 수 있습니다. var people = Object.create({}, { name: { value: 'Kim', enumerable: true } }); // 이번에는 people을 기반으로 새로운 객체를 생성합니다.(상속) var man = Object.create(people, { gender: { value: 'Male', enumerable: true } }); alert(man.name); // Kim alert(man.gender); // Male
Object.create() 메소드를 사용하면 기존의 객체를 기반으로 새로운 속성을 지정할 수 있으므로 상속이라고 볼 수 있습니다. 즉 man은 people을 상속해서 만들었다고 할 수 있습니다.
동적 속성 추가 제한
기존 자바스크립트의 모든 객체는 동적으로 속성 또는 메소드를 추가하거나 삭제할 수 있습니다. 하지만 ECMAScript 5부터는 동적으로 속성을 추가하는 것을 제한할 수 있습니다.
var obj = {}; // 간단한 객체 속성 추가 obj.gender = 'Male'; // 복잡한 객체 속성 추가 Object.defineProperty(obj, 'name', { value: 'Kim' }); if(Object.isExtensible(obj)) { // true Object.preventExtensions(obj); // 객체 속성 추가 제한(true->false) } alert(Object.isExtensible(obj)); // false // 객체 속성 추가 제한 후 객체 속성 추가 obj.region = 'Seoul'; alert(obj.region); // undefined(속성 추가 제한됨)
- Object.preventExtensions(객체명) : 객체의 속성 추가를 제한합니다.
- Object.isExtensible(객체명) : 객체의 속성 추가가 가능한지 확인합니다.(true/false)
동적 속성 삭제 제한
var person = { name: 'Kim', gender: 'Male' }; if(!Object.isSealed(person)) { // !false -> true Object.seal(person); // 동적 속성 삭제 제한 } alert(Object.isSealed(person)); // true // 동적 속성 삭제 제한 후 속성 삭제 delete person.gender; alert(person.gender); // Male 정상 출력
- Object.seal(객체명) : 객체의 속성 삭제를 제한합니다.
- Object.isSealed(객체명) : 객체의 속성 삭제가 가능한지 확인합니다.(true/false)
동적 속성 수정 및 삭제 제한
아래의 메소드는 객체 속성의 동적 수정 및 삭제를 제한합니다. 사용방법은 추가 또는 삭제와 같습니다.
- Object.freeze(객체명) : 객체의 속성 수정 및 삭제를 제한합니다.
- Object.isFrozen(객체명) : 객체의 속성 수정 및 삭제가 가능한지 확인합니다.(true/false)
객체 보조 메소드
- Object.keys(객체명) : 객체의 반복 순환 가능한 속성명으로 배열을 만듭니다.(enumerable: true인 것)
- Object.getOwnPropertyNames(객체명) : 객체의 모든 속성명으로 배열을 만듭니다.
- Object.getOwnPropertyDescriptor(객체명, 속성명) : 특정 속성의 옵션 객체를 추출합니다.
var obj = {}; Object.defineProperties(obj, { name: { value: 'Kim', enumerable: true }, gender: { value: 'Male' // enumerable 기본값 false } }); obj.region = 'Seoul'; // 기존 자바스크립트의 방식은 반복 순환 가능한 형태임 alert(Object.keys(obj)); // name, region alert(Object.getOwnPropertyNames(obj)); // name, gender, region
메소드 Object.keys()와 Object.getOwnPropertyNames()는 서로 비슷하지만 Object.keys() 메소드는 enumerable이 false인 것을 가져오지 못한다는 차이점이 있습니다. 따라서 위에서 gender가 출력되지 않았던 것입니다.
Object.getOwnPropertyDescriptor( )
var obj = { name: 'Kim' }; Object.defineProperty(obj, 'gender', { value: 'Male' }); // name 속성은 writable, enumerable, configurable이 기본적으로 true // gender 속성은 writable, enumerable, configurable이 기본적으로 false var descriptors = []; descriptors.push(Object.getOwnPropertyDescriptor(obj, 'name')); descriptors.push(Object.getOwnPropertyDescriptor(obj, 'gender')); // descriptors[0]: name 속성의 옵션 객체 // descriptors[1]: gender 속성의 옵션 객체 var output=''; for(var i in descriptors) { var item = descriptors[i]; for(var key in item) { output += key + ' : ' + item[key] + '\n'; } output += '\n'; } alert(output); /* 출력 결과 value : Kim writable : true enumerable : true configurable : true value : Male writable : false enumerable : false configurable : false */
Object.getOwnPropertyDescriptor()는 특정 객체의 옵션 객체를 추출합니다.