지적 코딩을 위한 매우 얕은 지식

Javascript/Js

JS 객체(3)

toy2508 2022. 6. 5. 23:53
반응형

1.  객체 직렬화

 - 객체 직렬화(serialize)는 객체를 문자열로 변환하는 작업이다.
 - JSON.stringify() : 객체에서 문자열로 변환(열거 가능한 프로퍼티만 직렬화함)

 - JSON.parse(): 문자열을 객체로 변환(date는 문자열 유지)

let obj = {x:1, y:{x: [false, null, ""]}}; 
let s = JSON.stringify(obj);  // s == '{"x":1, "y":{"z":[false,null,""]}}'
let p = JSON.parse(s); // p == {x:1, y:{z: [false, null, ""]}}

 

2. 객체 메서드

 - toString() 메서드 : 메서드의 인자가 없고, 호출되 객체의 값을 문자열로 반환
 - toLocaleString() 메서드 : toString()과 기능은 같으나, 숫자, 날짜, 시간을 지역에 맞게 문자열로 변환

 - valueOf() 메서드 : Numer()를 통해서 숫자로 변환할 때 호출 

 - toJson() 메서드 : Object.protoType에 정의된 메서드는 아니지만 JSON.stringify() 메서드는 직렬화할 
                               객체에서 toJSON()메서드를 검색하여 반환값을 직렬화한다.

//toString, toLocaleString
let point = {
	x: 1000,
    y: 2000,
    toString: function() { return `(${this.x}, ${this.y}`;},
    toLocaleString: function() {
    	return `(${this.x.toLocaleString()}, ${this.y.toLocalString()})`;
    }
};
point.toString()  // --> "(1000, 2000)"
point.toLocaleString() // --> "(1,000, 2,000)": 천 단위 구분자 있음


// valueOf
let point = {
	x: 3,
    y: 4,
    valueOf: function() { return Math.hypot(this.x, this.y); }
}

Number(point) // --> 5: 숫자로 변환할 때 valueOf()가 호출
point > 4 // --> true
point > 5 // --> false
point < 6 // --> true


// toJson
let point = {
	x: 1,
    y: 2,
    toString: function() { return `(${this.x}, ${this.y})`},
    toJson: function() { return this.toString(); }
}

 

3. 확장된 객체 리터럴 문법

  - 단축 프로퍼티 : 변수와 프로퍼티의 이름이 동일할 경우 프로퍼터 이름 하나만 표현하면 된다.
     ex)  let x  = 1, y = 2;
            let = { x, y }

  - computed property : 프로퍼티의 이름이 변수로 저장되어있을 때 객체를 만들고 프로퍼티를 
                                     추가하는 과정이 필요함

  -프로퍼티 이름인 심벌 : computed property를 통해 심벌을 프로퍼티 이름으로 이용 가능

const PROPERTY_NAME = "p1";
function computedPropertyName() { return "p" + 2 }

let p = {
	[PROPERTY_NAME]: 1,
    [computedPropertyName]: 2
}

p.p1 + p.p2 // => 3


//Symbol 이용
const extension = Symbol("my extension symbol")
let obj = {
	[extension]: { /* 이 객체에 확장 데이터를 저장합니다.*/}
}

obj[extension].x = 0;

 - 분해 연산자 : ...을 사용해 기존 객체의 프로퍼티를 새 객체에 복사할 수 있음
    1) 어떤 객체의 분해 연산자와, 그 객체의 동일한 프로퍼티 이름의 프로퍼티를 결합할 경우

        마지막에 위치한 프로퍼티의 값만 남는다.
    2) 상속된 객체는 분해 연산자에 포함되지 않는다.
    3) 분해 연산자를 많은 횟수의 루프나 재귀함수에 쓰게되면 성능이 저하될 수 있다.

let position = {x:0, y:0};
let dimensions = {width: 100, height: 75}
let rect = {...position, ...diemnsions};
rect.x + rect.y + rect.width + rect.height // => 175


let obj = {x: 1}
let p = {x: 0, ...obj};
p.x // --> 1: 객체 obj의 값이 초기값을 덮어쓴다.
let q = {...0, x: 2};
q.x // --> 2: 2라는 값이 o의 기존 값을 덮어쓴다.

 - 단축 메서드 :  객체 내에 프로퍼티 값이 메서드일때, 메서드명으로 프로퍼티명을 대체가능

let square = {
	area() { return this.side * this.side;}
    side: 10
};
square.area() // => 100

// Symbol, computed property 등 사용 가능
const METHOD_NAME = "m";
const Symbol = Symbol()
let = weirdMethods = {
	"method With Spaces"(x) { return x + 1;},
    [METHOD_NAME](x) { return x + 2;},
    [symbol](x) { return x + 3; }
}

weirdMethods["method With Spaces"](1) // --> 2
weirdMethods[METHOD_NAME](1) // --> 3
weirdMethods[symbol](1) // --> 4

 - 프로퍼티 게터와 세터 : 읽기와 쓰기를 가능하게 하는 프로퍼티

// 세터, 게터의 일반적인 사용
let obj = {
	// 일반적인 데이터 프로퍼티
    dataProp: value,
    // 함수의 쌍으로 접의된 접근자 프로퍼티
    get accessorProps() { return this.dataProp; },
    set accessorProps(value) {this.dataProp = value; }
}

// 응용1
let obj = {
	// x와 y는 일반적인 데이터 프로퍼티
    x: 1.0,
    y: 1.0,
    
    // r은 게터와 세터가 있는, 읽고 쓸 수 있는 접근자 프로퍼티
 	get r() { return Math.hypot(this.x, this.y) },
    set r(newValue) {
    	let oldValue = Math.hypot(this.x, this.y);
        let ratio = newValue / oldValue;
        this.x *= ratio;
        this.y *= ratio;
    }
    
    //theta는 게터만 읽기 전용 접근자 프로퍼티임
	get theta() { return Math.atan2(this.y, this.x); }
};

p.r // --> Math.SQRT2
p.theta // => Math.PI / 4

// 게터와 세터 프로퍼티 상속가능
let q = Object.create(p); //게터와 세터를 상속하는 새 객체
q.x = 3; q.y = 4; // q의 데이터 프로퍼티를 설정
q.r // --> 5: 상속된 접근자 프로퍼티 동작
q.theta // --> Math.atan2(4,3)

// 응용2 :  이 객체는 점점 증가하는 시리얼 번호를 만든다.
const serialnum = {
	// 이 데이터 프로퍼티에 다음 시리얼 번호가 들어간다.
    // 프로퍼티 이름에 있는 _는 이 프로퍼티를 내부에서만 사용한다는 의미
    _n:0,
    
    // 현재 값을 증가시켜 반환
    get next() {return this._n++;},
    
    // n에 새 값을 할당하지만 현재 값보다 커야한다.
    set next(n) {
    	if (n > this._n) this._n = n;
        else throw new Error("serial number can only be set to a larger value");
    }

}

serialnum.next = 10; // 시리얼 번호 시작을 정한다.
serialnum.next // --> 10
serialnum.next // --> 11: 실행할 때마다 값이 달라진다.

 

반응형

'Javascript > Js' 카테고리의 다른 글

JS 배열(2)  (0) 2022.06.10
JS 배열(1)  (0) 2022.06.06
JS 객체(2)  (0) 2022.06.01
JS 객체(1)  (0) 2022.05.29
JS 점프문  (0) 2022.05.28