JavaScript Property
Property의 값을 가져오려면
- . 연산자 : 연산자 우측에 Property 이름 "식별자"
- [] 연산자 : 연산자 우측에 Property이름의 "문자열 표현식"
Property 값 생성
var temp = {}
console.log(temp);
temp.newProperty = "a";
temp["new Property"] = "b";
console.log(temp);
output:
연관 배열로서의 객체
temp.newProperty : 식별자가 와야 함 -> 코딩할 때 fix됨.
temp.["new Property"] : 표현식을 인자로 받음 -> 프로그램 실행중 입력받은 것 사용 가능
function addName(nameList, name, studentNumber) {
nameList["name"] = studentNumber
}
// 이런 코드가 동작 한다는 뜻!
상속
객체에서 Property를 찾을 때, 고유 Property안에 찾고자 하는 Property가 없으면,
상속받은 Prototype 객체에서 해당 Property를 찾는다.
function inherit(p) {
if (p == null) throw TypeError();
if (Object.create) // ECMAScript 5 이상에 정의되어 있음
return Object.create(p);
}
var o = {};
o.x = 1;
var p = inherit(o); // 객체 o와 Object.prototype를 상속받는 객체
p.y = 2;
var q = inherit(p); // 객체 p와 o, Object.prototype을 상속받는 객체.
q.z = 3;
var s = q.toString(); // q 는 Object.prototype을 상속받았기 때문에 toString 사용가능
var result = q.x + q.y; // 값은 3
console.log(result);
Output :
상속받은 Prototype Property를 바꾸고 싶을 때
상속받은 Property 가 read only 라면 수정 불가.
그렇지 않다면 두 가지 경우의 수
- 고유 Property로 재정의 된다. // 기본
- Prototype Property 의 값이 재설정된다. // setter method가 정의되어있을 경우
Property 접근 에러
존재하지 않는 Property에 접근하는 경우
- 에러 발생하지 않음. -> undefined return
존재하지 않는 객체의 Property에 접근하는 경우
- 에러 발생
var temp2 = o.a;
console.log(temp2) // undefined
var length = o.a.length; // undefined에서 Property를 찾으려 해서 error
Output :
에러 방지
var len = temp2 && temp2.a && temp2.length
객체 o에 Property p를 설정할 수 없는 경우
- p가 o의 고유 Property이고 readonly일 경우
- 읽기전용 Property p 에는 값 설정할 수 없다.
- p가 상속된 Property 이고 readonly일 경우
- 동일한 이름의 고유 Property로 감출 수 없음.
- p가 고유 Property도, 상속받은 Property도 아닌데 extensible 속성이 false일 경우.
프로퍼티 삭제하기
delete 연산자. Property의 값이 아니라 Property 자체를 지움
delete book.author;
delete book["main title"];
- delete 연산자는
- 고유 프로퍼티만 지울 수 있다.
- 삭제에 성공, 프로퍼티가 존재하지 않아 영향을 미치지 못한 경우, return true를 한다.
o = {x:1}
delete o.x; // 삭제 성공 return true
delete o.x; // 존재하지 않아 return true
delete o.toString; // 고유프로퍼티가 아니라 아무일도 안일어나고 true
delete 1; // 말도 안 되지만 return true
* configurable 속성이 false 인 프로퍼티는 지우지 않는다.
아래는 nonreconfigurable
delete Object.prototype; // 지울 수 없음
var x = 1;
delete this.x; // 지울 수 없음
function f() {}
delete this.f; // 지울 수 없음
프로퍼티 검사
주어진 이름의 프로퍼티가 있는지 검사할 필요가 있을 때
- in 연산자
- hasOwnProperty()
- propertyIsEnumerable() : 추가적으로 enumerable 속성까지 true여야
- 단순히 Property에 접근
var oo = {x : 1};
console.log("x" in oo);
console.log("y" in oo);
console.log("toString" in oo);
console.log(oo.hasOwnProperty("x"));
console.log(oo.hasOwnProperty("y"));
console.log(oo.hasOwnProperty("toString"));
var ooo = inherit({y : 2});
ooo.x = 1;
console.log(ooo.propertyIsEnumerable("x")); // 고유 프로퍼티 열거 가능 -> true
console.log(ooo.propertyIsEnumerable("y")); // 상속받은 프로퍼티 -> false
console.log(ooo.propertyIsEnumerable("toString")); // 내장프로퍼티, 열거불가능 -> false
Output:
!== 와 === 연산자
- undefined 와 null 을 구분할 수 있음.
프로퍼티 열거하기
for / in loop
var o = {x:1, y:2, z:3};
for(p in o) {
console.log(p, o[p]);
}
Output :
상속받은 Property 생략, method 생략
for(p in o) {
if(!o.hasOwnProperty(p))
continue;
}
for(p in o) {
if(typeof o[p] === "function")
continue;
}
프로퍼티 Getter / Setter
ECMAScript 5 에서는 Property의 값을 getter / setter method로 대체할 수 있음.
단순히 값을 값는 "Data Property" 와 다른 "Accessor Property" 라고 한다.
- 프로그램이 객체의 Accessor Property에 접근하면 getter method의 반환 값이 Property 접근 표현식의 값이 됨.
- 프로그램이 객체의 Accessor Property의 값을 바꾸려고 하면 getter method가 실행된다. = 오른쪽의 값이 method의 인자로 전달된다.
getter / setter 존재 유무로 읽기전용, 쓰기전용 결정.
특이한 것 : setter 만 있으면 쓰기전용. read 하려고 하면 있음에도 undefined return
Accessor Property의 정의
var oo = {
// Data Property
data_prop: value,
get accessor_prop() { /* 함수 몸체 */},
set accessor_prop(value) { /* 함수 몸체 */ }
}
Example : 2차원 좌표와 극좌표를 가지는 Property
var p = {
x: 1.0,
y: 1.0,
get r() {
return Math.sqrt(this.x*this.x + this.y*this.y);
},
set r(newValue) {
console.log("in setter : ", newValue);
var oldValue = Math.sqrt(this.x*this.x + this.y*this.y);
var ratio = newValue / oldValue;
this.x *= ratio;
this.y *= ratio;
console.log("now x : ", this.x);
console.log("now y : ", this.y);
},
get theta() {
return Math.atan2(this.y, this.x);
}
}
var q = inherit(p);
q.x = 1; q.y = 1;
console.log(q.r);
console.log(q.theta);
q.r = 777
console.log(q.r);
console.log(q.theta);
Output
Example : 일련번호 생성
var serialnum = {
$n: 0, // 프로퍼티 이름의 $는 private 프로퍼티라는 힌트
get next() {return this.$n++;},
set next(n) {
if(n>=this.$n) this.$n++;
else throw "serial number can only be set to a larger value";
}
}
Property 속성
이름, 값, 그리고 속성
- value
- 데이터 프로퍼티의 값도 속성으로 본다.
- writeable
- 값 변경 가능 여부
- enumerable
- 열거가능 여부
- configurable
- 3가지 속성 변경 가능한지.
Property의 3가지 속성 값을 질의하고 설정할 수 있도록 하는 ECMAScript 5 API
라이브러리 만들 때 중요
- 프로토타입 객체에 method 추가 , 추가된 method를 내장 method처럼 열거할 수 없게 만들기 위해
- 변경, 삭제 불가한 프로퍼티를 정의, 객체를 고정(lock down) 시키기 위해
접근자 Property의 속성 표현 위해 Property descriptor라는 객체 사용.
데이터 Property의 Property descriptor
- value, writeable, enumerable, configurable 등의 Property를 가짐
접근자 Property의 Property descriptor
- get, set, enumerable, configurable
객체의 특정 Property에 대한 Property descriptor객체
-> Object.getOwnPropertyDescriptor() 를 통해 얻을 수 있음.
console.log(Object.getOwnPropertyDescriptor({x:1}, "x"));
// 없는 Property거나 상속받은 Property 는 undefined
console.log(Object.getOwnPropertyDescriptor({}, "x"));
console.log(Object.getOwnPropertyDescriptor({}, "toString"));
Output
getOwnPropertyDescriptor 는 고유 프로퍼티만 검사 가능.
상속된 프로퍼티를 검사하고 싶으면 프로토타입 chain을 명시적으로 순회해야함.
프로퍼티의 속성 설정, 임의의 속성으로 새 프로퍼티를 만들기 위해
Object.defineProperty()
console.log(o);
Object.defineProperty(o, "x", {value : 1,
writeable: true,
enumerable: false,
configurable: true})
console.log(Object.getOwnPropertyDescriptor(o, "x"));
Output
동시에 여러개
var p = Objet.defineProperties({}, {
x: {value:1, writeable: true, enumerable:true, configurable: true},
y: {value:1, writeable: true, enumerable:true, configurable: true},
r: {get: function() {
return Math.sqrt(this.x*this.x + this.y*this.y);
},
writeable: true,
configurable: true}
})
객체 속성
모든 객체는 prototype, class, extensible 속성을 가지고 있음.
Extensible 속성
객체에 새 프로퍼티를 추가할 수 있는지 여부
목적 : 잠겨있는 객체의 상태를 고정, 외부에서 변경하는 것을 막는 것.
객체 직렬화
- JSON.stringify()
- JSON.parse()
'웹 프로그래밍 > Javascript' 카테고리의 다른 글
Javascript Function (0) | 2020.06.24 |
---|---|
Javascript Scope, 변수 (0) | 2020.06.23 |
Javascript Array (0) | 2020.06.23 |
JavaScript Object 생성 (0) | 2020.06.19 |
Javascript 세미콜론 (0) | 2020.05.30 |