JavaScript

[JavaScript] ECMAScript 5

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()는 특정 객체의 옵션 객체를 추출합니다.

댓글

댓글 본문
버전 관리
miki
현재 버전
선택 버전
graphittie 자세히 보기