Recent Posts
Recent Comments
Link
06-30 12:53
Today
Total
관리 메뉴

삶 가운데 남긴 기록 AACII.TISTORY.COM

javascript object property 본문

DEV&OPS/Javascript

javascript object property

ALEPH.GEM 2022. 3. 2. 14:11

프로퍼티

데이터 프로퍼티: 값을 저장하기위한 객체의 맴버 변수

접근자 프로퍼티: 데이터 프로퍼티에 접근하기 위한 함수를 정의한 프로퍼티

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title> </title>
    <script>
        var person = {
            _name: "Tom",
            get name(){
                return this._name;
            },
            set name(value){
                var str = value.charAt(0).toUpperCase() + value.substring(1);
                this._name = str;
            }
        };
        console.log(person.name);
        person.name = "huck";
        console.log(person.name);
    </script>
</head>
<body>

</body>
</html>

getter 와 setter를 정의하면 데이터 프로퍼티에 접근 할 수 있습니다.

delete person.name 처럼 delete 연산자로 프로퍼티를 삭제할 수 있습니다.

 

캡슐화

즉시 실행 함수로 클로저를 생성하면 데이터를 외부에서 숨기고 접근자 프로퍼티(getter, setter)로만 읽고 쓰고 할 수 있습니다.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title> 캡슐화 </title>
    <script>
        var person =(function(){
            var _name = "Tom";      /* private */
            return {
                get name(){
                    return _name;
                },
                set name(value){
                    var str = value.charAt(0).toUpperCase()+value.substring(1);
                    _name = str;
                }
            };
        })();
        console.log(person.name);   /* Tom */
        person.name = "huck";
        console.log(person.name);   /* Huck */
    </script>
</head>
<body>

</body>
</html>

 

프로퍼티 디스크립터(property descriptor)

프로퍼티 디스크립터는 해당 프로퍼티의 설정을 기술하는 객체입니다.

프로퍼티의 쓰기 가능 여부 등을 설정 할 수 있게 도와줍니다. 

데이터 프로퍼티의 디스크립터

{
    value: 프로퍼티의 값,
    writable: 쓰기 가능 여부 boolean,
    enumerable: 열거 가능 여부 boolean,
    configurable: 재정의 가능 여부 boolean
}

접근자 프로퍼티의 디스크립터

{
    get: getter 함수 값,
    set: setter 함수 값,
    enumerable: 열거 가능 여부 boolean,
    configurable: 재정의 가능 여부 boolean
}

 

Object.getOwnPropertyDescriptor(객체참조, 객체의프로퍼티이름)

해당 프로퍼티의 디스크립터를 가져오는 함수입니다.

프로토타입으로 상속받은 프로퍼티나 없는 프로퍼티를 지정하면 undefined를 리턴합니다.

var tom = {name: "Tom"}
Object.getOwnPropertyDescriptor(tom, "name");
//{value:"Tom", writable: true, enumerable:true, configurable:true}

 

Object.defineProperty(객체참조, 프로퍼티의이름, 프로퍼티 디스크립터의 참조)
var obj = {};
Object.defineProperty(obj, "name", {
     value: "Tom",
     writable: true,
     enumerable: false,
     configurable: true
 });

프로퍼티 디스크립터의 4개 항목은 생략이 가능합니다.

생략하게 되면 false나 undefined로 설정됩니다.

var person = { name: "Tom"};
Object.defineProperty(person, "name", {
    writable: false;
});
person.name = "Huck";
console.log(person.name); 	//Tom
//디스크립터의 writable을 false로 설정했기 때문에 person.name값이 바뀌지 않습니다.

 

Object.create(프로토타입, 프로퍼티 디스크립터)

Object.create()으로 인스턴스를 생성할 때 첫번째 인수는 프로토 타입으로 상속을 받을 객체를 지정하고 두번째 인수로 프로퍼티 디스크립터를 기술할 수 있습니다.

var group ={
    groupName: "Tennis circle",
    sayGroupName: function(){console.log("belong to " + this.groupName);}
}
var person = Object.create(group, {
    name: {
        value: "Tom",
        writable: true,
        enumerable: true,
        configurable: true
    },
    age: {
        value:18,
        writable: true,
        enumerable: true,
        configurable: true
    },
    sayName: {
        value: function(){console.log("I am " + this.name);},
        writable: true,
        enumerable: false,
        configurable: true
    }
});
console.log(person);	//Object{name: "Tom", age: 18}
console.log(person.groupName);	//Tenis circle
console.log(person.sayGroupName());		//belong to Tennis circle
console.log(person.sayName());		//I am Tom

 

프로퍼티 관련 연산자와 메서드

자바스크립트는 객체(인스턴스)를 동적으로 바꿀 수 있기 때문에 우리가 사용하고자 하는 프로퍼티가 있는지 확인할 필요가 있습니다.

in 연산자

지정한 프로퍼티가 그 객체의 프로퍼티이거나 상속받았다면 true, 아니면 false를 리턴합니다.

var person = {name: "Tom"};
console.log("name": in person);		//true
hasOwnProperty 메서드

해당 프로퍼티가 그 객체가 소유한 프로퍼티이면 true, 상속받았다면 false를 리턴합니다.

var person = {name: "Tom"};
console.log(person.hasOwnProperty("name"));		//true
console.log(person.hasOwnProperty("toString"));		//false , 상속 받았기 때문
propertyIsEnumerable 메서드

해당 프로퍼티가 그 객체가 소유한 프로퍼티이며 열거할 수 있으면 true를 리턴합니다.

 

프로퍼티의 열거

for ... in ...

열거 가능한 객체를 처음 부터 끝까지 하나씩 열거해 줍니다.

Array는 다른 언어들과 달리 객체이기 때문에 배열의 인덱스가 프로퍼티 이름이며 값은 프로퍼티 값 으로 되어 있습니다.

Array는 프로토타입에서 상속 받은 length나 push등을 사용할 수 있지만 프로토타입은 열거 할 수 없기 때문에 for/in으로는 찾아낼 수 없습니다.

Object.keys 메서드

지정한 객체가 소유한 프로퍼티중에서 열거할 수 있는 프로퍼티 이름만 배열로 리턴합니다.

var group = {groupName: "Tennis circle"};
var person = Object.create(group);
person.name = "Tom";
person.age = 17;
person.sayHello = function(){console.log("Hello " + this.name);};
Object.defineProperty(person, "sayHello",{enumerable:false});
console.log(Object.keys(person));		//["name", "age"]
Object.getOwnPropertyNames 메서드

인수로 지정한 객체가 소유한 프로퍼티 이름을 배열로 리턴합니다.

열거할 수 없는 프로퍼티까지 모두 배열로 만드는 점이 Object.keys와 다른점입니다.

 

객체 잠금

확장(extend)방지: Object.preventExtensions 메서드

인수로 받은 객체를 확장(프로퍼티 추가)을 할 수 없게 합니다. 이후 추가한 프로퍼티는 무시됩니다.

Object.seal 메서드

인수로 받은 객체를 seal(봉인) 합니다. 프로퍼티의 추가와 재정의를 못하게 합니다. 프로퍼티 값의 읽기 쓰기만 가능해집니다.

Object.freeze 메서드

인수로 받은 객체를 freeze(동결) 합니다. 객체의 프로퍼티가 읽기만 가능한 상태가 됩니다. 단 getter,setter가 정의되어 있는 경우에는 값을 getter와 setter를 통해 접근과 수정이 가능합니다.

 

믹스인(Mixin)

다른 두 객체의 프로퍼티를 합칠 수 있습니다.

function mixin(target, source){
    var keys = Object.keys(source);
    for(var i = 0; i<keys.length; i++){
        var descriptor = Object.getOwnPropertyDescriptor(source, keys[i]);
        Object.defineProperty(target, keys[i], descriptor);
    }
    return target;
}

심볼을 키로 갖는 프로퍼티는 복사되지 않습니다.

target 객체가 이미 소유하고 있는 프로퍼티 값은 덮어쓰게 되고 source객체의 나머지 프로퍼티들은 추가가 되게 됩니다.

Object.assign 메서드를 이용하면 위와 같은 mixin 작업을 할 수 있습니다.

 

 

 

 

 

 

 

 

 

728x90

'DEV&OPS > Javascript' 카테고리의 다른 글

javascript 알고리즘 연습  (0) 2022.03.02
JSON  (0) 2022.03.02
javascript prototype  (0) 2022.02.23
javascript ECMAScript 6부터 추가된 함수와 객체의 기능  (0) 2022.02.21
javascript 함수2  (0) 2022.02.21