javascript 빌트인 object 이해하기(3) - Object
javascript 빌트인 object 이해하기(2-2) - String
javascript 빌트인 object 이해하기(2-1) - String
javascript 빌트인 object 이해하기(1) - Number
javascript 빌트인(Built-in) 이해하기
javascript 연산자(Operator) 이해하기
Prototype과__proto__
이해하기(1)
Prototype과__proto__
이해하기(2)
이번에 알아볼 자바스크립트의 빌트인 오브젝트는 Object이다.
보통 객체를 object라고 많이 표현하기때문에, String object와 같이 Object object로 표기하기도 해서 헷갈린다.
소문자 object는 객체를 의미하므로 프로퍼티를 가질 수 있다는 의미를 내포하고있고
앞에 대문자로 붙는 Object는 객체의 타입을 의미한다고 생각하면 된다.
빌트인 Object 객체 property
(ES3기준)
Object 객체 생성 : new Object(), Object(),{}
new Object()
new Number(123)
, new String(123)
의 경우엔, 각각 Number instance 와 String instance를 생성한다.
new Object(123)
의 경우는 어떨까? Object instance를 생성할까? 아니다. 파라미터의 데이터 타입에 따라 생성할 인스턴스가 결정된다.
- 파라미터의 데이터 타입에 따라 생성할 인스턴스 결정(
String
,Number
,Object
등 가능) - 파라미터 값이
undefined
,null
이면 빈Object
인스턴스 반환 {}
Object()
new Object()
와 같다- 파라미터의 데이터 타입에 따라 생성할 인스턴스 결정(
String
,Number
,Object
등 가능) - 파라미터 값이
undefined
,null
이면 빈Object
인스턴스 반환 {}
{}
- 파라미터는
key:value
형식만 가능 (123, "123" 불가능) ( Object 인스턴스만을 반환 가능) - 그 외에
new Object()
와Object()
와 동일 - Object 인스턴스 생성할 땐,
new Object()
와Object()
와 동일하므로, 간단하여 자주 활용됨
let newObj1 = new Object(123); // Number 인스턴스 생성
console.log(newObj1); // Number {123}
let newObj2 = Object("123"); // String 인스턴스 생성
console.log(newObj2); // String {123}
let newObj3 = {123}; // SyntaxError : Unexpected number
let newObj3 = {height:123} // 오브젝트 인스턴스 생성
valueOf()
Object
인스턴스의 프리미티브 값 반환
hasOwnProperty()
- 인스턴스에 파라미터 이름이 존재할경우
true
, 존재하지 않을시false
반환 ( 값의 존재여부는 따지지 않음) - 자신의 고유 property는 없고, 상속받은 property(
__proto__
에 존재하는 property)일 경우 false 반환
const obj = {value : undefined};
console.log(obj.hasOwnProperty("value")); // 값에 상관없이 value라는 key가 존재하므로 true 반환
console.log(obj.hasOwnProperty("hasOwnProperty")); // Object 의 prototype에 hasOwnProperty가 존재하지만, 자신의 고유 property에는 존재하지 않기때문에 false를 반환
toString()
- 인스턴스 타입을 문자열로 표시
const point = {book:"책"};
console.log(point.toString()); // [object Object]
ES5 Object
ES5 Object의 특징
Object
에 메소드가 추가됨, 대신 이 메소드는 Object
의 protype
에 정의되어있지 않다. 따라서
- 상속되지 않고,
Object
객체만이 활용함 Object.메소드
형식으로 활용❓왜 prototype에 추가하지 않고, 자체 메소드로만 추가했을까?
❗prototype 내에 정의되어있다면, 대부분의 객체는 Object를 조상으로 삼기때문에 대부분의 빌트인 object 에 첨부되고, 이러한 빌트인 object를 통해 인스턴스 생성하면, Object의 prototype과 연결이 많이 발생 (Object 객체만이 활용가능한 메소드로 정의할 경우, 연결 부하를 줄일 수 있음)
Prototype과__proto__
이해하기(1)
Prototype과__proto__
이해하기(2)
추가된 것
- method
- property descriptor
defineProperty()
- 대상 객체에 프로퍼티 추가 혹은 속성 변경
- property마다 상태(변경/삭제/열거 가능 여부)를 갖고 있는데, 상태가 가능일때만 처리할 수 있음
- property 추가할 때, 상태도 결정할 수 있음(default값 :
false
)
let obj = {};
Object.defineProperty(obj, "book",{
value : "JS책", // 프로퍼티 value 설정
enumerable : false // 프로퍼티 상태 결정
});
for (let name in obj){
console.log(name + ":" + obj[name]); // undefined(열거불가능))
}
defineProperties()
- 다수의 프로퍼티를 추가하거나 속성 변경
- 함수 기능은
defineProperty()
와 같음
- 함수 기능은
let obj = {};
Object.defineProperties(obj,{
soccer : {
value : "축구", enumerable : true
},
basketball : {
value : "농구", enumerable : true
}
});
for (let name in obj){
console.log(name + ":" + obj[name]); // soccer:축구 basketball:농구(열거가능)
}
getPrototypeOf()
- 파라미터의 prototype에 연결된 property 반환 (
setPrototypeOf()
는 ES5는 스펙에 없고, ES6에 존재 )
객체.__proto__
보다는Object.getPrototypeOf(객체)
와 같은 사용을 권장하고 있음
getOwnPropertyNames()
- 객체의 property 이름을 배열로 반환
- 열거 가능 여부는 체크하지 않음 (
enumerable
이false
여도 반환됨) - 객체 자신이 만든 property가 대상(상속받은건 제외)
keys()
- 객체의 property 중 열거가능한 property 이름을 배열로 반환
- 객체 자신이 만든 property가 대상(상속받은건 제외)
property descriptor
property descriptor : property의 속성 이름과 속성 값을 정의
위의 예시에선, 프로퍼티의 값(value)
속성에 값을 정의하고,enumerable
속성에 값을 할당하는 것이 보여졌다.
이처럼, ES5엔 value
뿐만 아니라 다양한 property descriptor 가 새로이 정의되었다.
descriptor type 분류
- data property descriptor :
value
,writable
- access property descriptor :
get
,set
- 공용 property descriptor :
enumerable
,configurable
descriptor type 인식 기준
- data 와 access property descriptor는 함께 작성할 수 없다. (이후 좀 더 자세한 설명...)
❓ES5에서 상태를 결정할 수 있게 한 이유는?
❗오픈소스로 코드를 공개하게 될때, ES5전까지는 일부는 코드를 보고서 자신의 데이터에 접목?시킬 수도 있었다. 따라서, 이러한 속성을 활용하여 데이터를 보호하는 차원이 주된 이유 중 하나이다.
value
- property의 값 ( default :
undefined
) get
/set
속성과 같이 작성 불가
writable
- property
value
속성값 변경 가능(true
)/불가능(false
(default)) false
일 경우, 변경 시도시 에러가 발생하지 않지만, 값이 변경되지 않음get
/set
속성과 같이 작성 불가
enumerable
for...in
으로 열거 가능(true
)/불가능(false
(default))
configurable
- property 삭제 가능(
true
)/불가능(false
(default)) true
:value
이외 속성 변경 가능 / 프로퍼티 삭제 가능false
: 프로퍼티 삭제 불가,value
이외 속성 변경 불가
let obj ={};
Object.defineProperty(obj,"book",{
value :"JS책",
writable : false, // value 변경불가
configurable : true // value이외 속성값 변경 가능 / 프로퍼티 삭제 가능
});
obj.book = "goggling책";
console.log(obj.book); // JS책(value 변경안됨)
delete obj.book; // 프로퍼티 삭제 가능
console.log(obj.book); //undefined
get
- default :
undefined
객체.프로퍼티
를 호출할 때, value 속성이 정의되지 않았을 경우, get 함수의 리턴값 반환- data type property descripter와 동시 사용 불가 (
value
와 함께 작성시 : 누굴 반환해야하지? 되므로 동시 작성 불가 /writable
과 함께 작성시 : 함수의 value값을 변경 가능/불가능을 설정하는 descriptor인데 value 값이 get과 존재할 수 없으므로 동시 작성 불가) 객체.프로퍼티.get()
처럼 함수로 호출하면 에러 발생
set
- default :
undefined
객체.프로퍼티 = value
를 작성할 때, value 속성이 정의되지 않았을 경우, set 함수에 해당value
가 parameter로 들어가고, 리턴값을 프로퍼티에 할당함- data type property descripter와 동시 사용 불가 (
value
와 함께 작성시 : 누구의 값으로 설정하지? 되므로 동시 작성 불가 /writable
과 함께 작성시 : 함수의 value값을 변경 가능/불가능을 설정하는 descriptor인데 value 값을 변경할지, set의 return 값을 변경할지 알수없으므로 동시 작성 불가) 객체.프로퍼티.set()
처럼 함수로 호출하면 에러 발생
let obj = {}
Object.defineProperty(obj, "book", {
set : function(param){
obj.title = param.toUpperCase(); // parameter를 받아 대문자로 바꿔줌
},
get : function(){
return obj.title;
}
});
obj.book = "jsbook"
console.log(obj.book); //JSBOOK
property descriptor 메소드
getOwnPropertyDescriptor()
- property descriptor의 속성과 값 반환
Object.getOwnPropertyDescriptor(객체이름, property;
preventExtensions()
재해석 : 객체 확장 금지! (객체 몸집을 그만불려라..)
- 객체에 property 추가 금지 설정
- property 삭제, 변경은 가능
- 추가 금지로 설정한 경우, 추가 가능으로 변경 불가
Object.preventExtensions(객체이름)
isExtensible()
- 객체에 property 추가 금지 여부 반환[
true
,false
]
seal()
재해석 : 객체 밀봉! (객체의 형태를 건들 수 없습니다. 건드리려면 밀봉을 풀어주세요)
- 객체에 property 추가 및 삭제 금지 설정 (시도시,error는 나지 않으나, 변경안됨)
- 객체의 property의 모든 속성이 설정 불가능(non-figurable) 해짐 (시도시,error는 나지 않으나, 변경안됨)
- 속성값은 변경 가능 ( 속성값의 변경을 제외한 어떤 변경도 적용되지 않음 )
조금 헷갈리니깐...
다시 재해석 : 객체 밀봉! 외부에서 만지작거리는건 안되고(ex. defineProperty
와 같은 형태)
내부에서 속성값 변경은 가능(ex. 객체.프로퍼티 로 접근하여 변경)
isSealed()
- 객체의 seal 여부 반환 [
true
,false
]
freeze()
- 객체 동결! 불변함
- 동결이지만, 얕은 동결(shallow freeze)이라고 부른다. 왤까? 아래 질문을 생각해 볼 수 있다.
❓ 객체의 프로퍼티 값이 객체라면? 객체의 객체(inner 객체)도 과연 동결이 될까요? 아니요.
❓ * inner 객체를 포함한 객체의 객체의 객체의 객체.... 를 모두 동결 시키려면 어떻게 해야할까요?❗이런 것을 수행하기 위한,
deepFreeze()
라는 개념도 존재한다.
Object.seal()
과의 비교 :Object.seal()
을 사용해 봉인된 객체는 존재하는 속성을 변경할 수 있습니다.Object.freeze()
로 동결된 객체에서는 존재하는 속성이 불변입니다.
isFrozen()
- 객체의 freeze 여부 반환 [
true
,false
]
이걸 다 외우는 건 있을 수 없는 일이고, 개념과 동작원리를 알고 나중에 필요할 때 서치하여 활용할 수 있는정도만 알아두면 충분할 것이다.
내용에 오류가 있으면 알려주시면 감사합니다!
Author And Source
이 문제에 관하여(javascript 빌트인 object 이해하기(3) - Object), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@goggling/javascript-object-이해하기3-Object저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)