JS - Objects 객체에 대한 모든 것 링크
- JS - Objects 객체에 대한 모든 것 - 1
- JS - Objects 객체에 대한 모든 것 - 2
- JS - Objects 객체에 대한 모든 것 - 3
- JS - Objects 객체에 대한 모든 것 - 4
- JS - Objects 객체에 대한 모든 것 - 5
JS - Objects 객체에 대한 모든 것
1 부터 ~ 5 까지 쭉 이어서 보는걸 권장한다.
자바스크립트의 오브젝트에 대해서 우리가 일반적으로 키/값 대입 이러한 일반적인 방식으로 사용을 해왔다면
이번 내용부턴 자바스크립트 자체가 Object 라는 객체에 대해 정적메서드
즉, 프로토 타입 쉽게 말해 그냥 객체가 그냥 내부적으로 가지고 있는 내부 메서드라고 생각하면 쉽다.
이 내용을 이해하려면 프로토 타입에 관련된 내용을 어느정도 숙지하고 있어야 이해가 쉽다.
암튼 이 내부 메서드를 정리를 해볼건데, 이 내부 메서드를 완벽히 이해하고 잘 이용을 한다면
자바스크립트의 오브젝트 다루는거에 있어서 고수가 될 수 있다.
'나는 그냥 자바스크립트 일반적인 사용법으로도 큰 불편을 못 느낀다.' 혹은
'나는 일반적인 객체 다루는 법으로도 충분히 코딩을 해오면서 큰 불편을 못느꼈다'
라고 하시는 분들은 이 내용이 크게 와 닿지 않을 것이다.
하지만 내가 좀더 자바스크립트에 대해서 깊게 알고 싶고, 코드도 좀더 정리화 시키면서
수준높은 코딩을 하고 싶다면 이 내용이 도움이 될 것이다.나도 공부하면서 배우는 지식을 하나씩 글을 남기면서 공부 중인데 상당히 도움이 됐다.
어느 부분에서 도움이 가장 컸냐면... 자바스크립트 언어로 개발을 진행하다보면 분명 외국 개발자들이 만들어놓은
오픈 소스라던가... 아니면 누구나 가져다 사용할 수 있게 자바스크립트 라이브러리 라던가.. 등등
이 라이브러리 혹은 오픈소스를 내가 가져다가 개발을 진행 했을 때,
그 오픈소스와 라이브러리를 사용하는데 어려움이 현저히 줄어들었다.
즉, 라이브러리를 가져다 사용할 때도, 정해진 가이드로만 사용한다면 사용 범위가 상당히 좁은데,
내가 어느정도 자바스크립트의 숙련도가 높다면 다른 외국개발자들이 만들어놓은 라이브러리라던가
혹은 오픈소스를 내 입맛대로 부분부분 수정해서 사용 할 수 있는 숙련도가 생긴다.
그래서 자바스크립트의 깊은 이해도를 원한다면 이 글을 읽어보는것이 도움이 될 것이다.
자 이제 시작해본다.
자바스크립트에 ES5 이전에는 오브젝트 객체에 대해 읽기 전용 속성인지 아닌지
검사하거나 구분할 수 있는 직접적인 방법을 제공하지 않았다고 한다.
ES5부터는 제공한다는데 이게 프로퍼티 설명,
즉 속성 설명 자라고 한다.
▶ 속성(프로퍼티) 설명자
속성 설명자 라고 해서 이건 자바스크립트 내부 메서드 즉, 정적메서드인 객체에 프로토 타입으로 들어가져있는 메서드이다.
아래 내용을 통해 자세히 알아보자.
Object.getOwnPropertyDescriptor(오브젝트, 속성);
→ 오브젝트를 매개변수를 넣어 속성(프로퍼티)을 넣으면 이 객체에 대한 데이터 설명자들이 나온다.
이 설명자는 정적 메서드로써 객체 속성의 정보만 확인할 수 있다.
writable, enumerable, configurable 이러한 속성을 볼 수가 있다.
var test = {
a:10
}
var obj = Object.getOwnPropertyDescriptor(test, "a");
console.log(obj);
위 코드를 보면 test라는 객체에 a라는 프로퍼티(속성) 값을 넣어서
콘솔 로그로 obj를 찍어보면 아래와 같은 속성들을 볼 수 있다.
단, 이 메서드는 정적 메서드라 속성을 추가하거나 변경이 안된다.
위 코드에서 test라는 객체의 속성 정보를 확인만 가능하다.
아래 결과 화면을 보면 a라는 속성의 값은 10이고,
이 a라는 속성의 writable, enumerable, configurable 이 3가지 속성 값이 true라는 걸 볼 수 있다.
자 이 속성 설명자를 알아봤는데? 어떤가?
그냥 일반적으로 웹 개발하면서 과연 이게 필요할까? 라는 의문이 들지 않은가?
그렇다 그렇게 크게 와 닿지 않은 내용이다.
나도 그랬다. 하지만 이걸 어느때에 사용하는가? 라고 묻고 쓸 수 밖에 없는 순간을 맞이 할 땐
그리고 사용을해서 문제를 풀었다면...
한층 더 자바스크립트 다루는 기술에 대해 레벨업을 했다고 생각해도 된다.
내 경험을 비추어서 얘기를 해보자면
어떤 모듈을 개발해야 하는데, MIT 라이브러리 오픈소스를 가져다가 사용을 하는데
문제는 이 라이브러리의 모든 소스를 사용하려고 한게 아니라 어느 부분만 가져다가
커스터마이징 하여 사용을 하려고 했는데, 문제는 여기서 생겼다. 객체의 값을 고쳐서 내 입맛대로 무언가를 개발하려는데 계속해서 값이 변경이 안되거나... 값이 대입이 안되거나 이러한 경험을 얻었다.
자바스크립트의 객체는 속성을 갖는데 이 속성의 값에 따라 값을 대입하게 할 수 있다던지, 혹은 값을 변경을 한다던지 이러한 행위들을 전부 컨트롤 할 수가 있다.
바로 저 3가지 속성이 현재 어떻게 셋팅이 되어있는지에 따라 객체을 컨트롤 할 수가 있는 것이다. 그러므로 저 속성 설명자를 이용하여 현재 객체가 어떤 속성의 셋팅이 되어있는지 확인이 가능하다.
그런데 왜? 라이브러리라던가 오픈소스들은 이런걸 적용해서 만들어 놨을까?
라는 생각을 할 수도 있다. 그러나 조금만 생각하면 이건 당연한거다...
오픈소스나, 라이브러리 소스는 누구나 가져다가 사용 할 수 있게 만들어논 소스인데,
이 원본의 소스는 사용자가 무슨 짓을 하던간에 원본소스는 변경이 안되는 선에서 사용가능하게 만들어 논건데
이런 이유로 원본 소스는 외부에서 변경이 안되게 막고, 사용하는 방법 즉,
가이드만 제공하여 사용하게끔 만들어 논 것이 오픈소스 라이브러리이다.
그래서 결론은 객체에 대한 내부 메서드 즉, 프로토타입에 관련해서 좀 더 깊은 지식이 있다면
라이브러리 오픈소스 등 내가 커스터마이징 할 수 있는 힘이 생긴다.
이렇듯 객체에 대해 좀더 깊게 공부를 원한다면 이 글을 계속 보는것을 권장한다.
다음 내용은 또 어떤 내부 메서드가 있는지 알아보자.
▶ 객체 속성 추가
Object.defineProperty(오브젝트, 속성, {객체의 데이터})
→ 새 속성을 추가하거나 기존 속성을 수정할 수 있다.
var obj = {}; // 빈 객체 선언
Object.defineProperty(obj, "test", {
value:'이렇게 사용하여 값을 지정',
writable:true,
configurable:true,
enumerable:true
});
console.log(obj.test) // 이렇게 사용하여 값을 지정
빈 객체 obj를 선언하고 Object.defineProperty를 이용하여 test라는 프로퍼티에
value 에다가 값('이렇게 사용하여 값을 지정')을 지정하고,
이 test라는 프로퍼티(속성)의 데이터 값 writable, enumerable, configurable 전부 true를 줬다.
이제 각각 writable, enumerable, configurable 이 3가지가 무엇인지 알아보자.
1. writable
이 속성은 프로퍼티의 value를 변경 여부를 나타낸다.
아래 예시를 보자.
var obj = {}; // 빈 객체 선언
Object.defineProperty(obj, "test", {
value:'이렇게 사용하여 값을 지정',
writable:false, // < --- false 로 지정함
configurable:true,
enumerable:true
});
obj.test = '10';
console.log(obj.test); // 이렇게 사용하여 값을 지정
writable을 false로 고정하면 아래처럼 obj.test 에 새롭게 '10' 값을 지정해도 값이 변경되질 않는다.
즉, obj 객체 안에 test라는 속성의 데이터 속성 중 writable을 false로 지정하면
아무리 값을 변경하려 해도 변경이 불가능하다.
이처럼 writable 은 객체 속성의 값을 변경 여부를 나타낸다.
위 코드에 엄격 모드일 땐? 어떤 결과가 일어날까?
'use strict'; // 엄격모드 선언
var obj = {}; // 빈 객체 선언
Object.defineProperty(obj, "test", {
value:'이렇게 사용하여 값을 지정',
writable:false, // < --- false 로 지정함
configurable:true,
enumerable:true
});
obj.test = '10'; // <---- TypeError 가 발생됨.
console.log(obj.test); // 이렇게 사용하여 값을 지정
이렇게 엄격 모드일 땐 타입 에러가 발생한다.
test라는 속성(프로퍼티)의 데이터 속성 중 writable을 false 고정해놨는데,
obj.test = '10'이라는 코드로 값을 변경하려고 하니 에러가 발생이 됐다.
엄격 모드에선 타입 에러가 발생된다는 것을 주의하자.
2. configurable
이 속성도 wirtable과 같은 기능이지만 차이점이 있다.
이 속성도 예제를 통해서 알아보자.
var obj = {}; // 빈 객체 선언
Object.defineProperty(obj, "test", {
value:'100',
writable:true,
configurable:true,
enumerable:true
});
Object.defineProperty(obj, "test", {
value:'100',
writable:true,
configurable:false, // < --- false 로 지정함
enumerable:true
});
obj.test = '10';
console.log(obj.test); // 100
Object.defineProperty(obj, "test", {
value:'100',
writable:true,
configurable:true, // <--- 다시 true 변경함
enumerable:true
}); // ---> TypeError 발생됨.
console.log(obj.test)
위 코드를 살펴보자. 위 코드는 obj에 빈 객체를 선언하고,
그다음 Object.defineProperty를 이용하여 test라는 속성(프로퍼티)에 값을 100을 주었다.
그리고 configurable에 true를 설정했다.
그리고 두 번째에 Object.defineProperty를 이용하여 configurable 에 false를 설정하고,
그래서 난 값을 변경하려고 다시 Object.defineProperty를 이용하여
test라는 속성(프로퍼티)의 데이터 속성 중 configurable을 true 바꿨다.
그런데 TypeError가 발생했다.
이 속성은 엄격 모드가 아니더라도 TypeError가 발생된다.
즉, false로 값을 변경 한 순간 또는 처음부터 false로 값을 설정한 것이 true로 재설정하려고 하는 순간
에러가 발생이 되는 거라 writable 속성과 차이점이 있다.
그리고 configurable의 기능은 false 일 땐 속성을 삭제하려고 해도 삭제가 안된다.
예시를 보자.
var obj = {}; // 빈 객체 선언
// -------------------- 1번 예시 ----------------------//
Object.defineProperty(obj, "test", {
value:'100',
writable:true,
configurable:true,
enumerable:true
});
console.log(obj.test); // 100
delete obj.test;
console.log(obj.test); // undefined
// -------------------- 1번 예시 ----------------------//
// -------------------- 2번 예시 ----------------------//
Object.defineProperty(obj, "test", {
value:'100',
writable:true,
configurable:false, // < --- false 로 지정함
enumerable:true
});
console.log(obj.test); // 100
delete obj.test;
console.log(obj.test); // 100
// -------------------- 2번 예시 ----------------------//
1번 예시를 봐보자.
configurable의 설정은 true 했다.
obj.test 는 100의 값을 가졌다.
delete 연산자로 속성(프로퍼티)을 삭제했고,
다시 console.log로 찍어보니 undefined가 찍혔다.
2번 예시를 봐보자.
configurable의 설정을 false로 바꿨고,
delete 연산자로 삭제 코드를 했고 그다음에 console.log로 찍어보니 삭제가 안되었다.
그대로 100 찍혀서 나오는걸 볼 수 있다.
이처럼 configurable을 false로 설정을 하면 객체의 속성(프로퍼티) 삭제를 할 수가 없다.
보이는가? 이렇게 객체에 속성을 삭제할 수 없는 속성을 지정하면 아무리 외부에서 변경을 해도,
삭제, 대입, 변경 등등 조작이 불가능하다.
대부분 라이브러리 오픈소스 내부를 잘 들여다 보면 저렇게 기본 디폴트 값을 변경되지 않게
이런식으로 내부 객체에 설정을 해 놓는다.
자 다음 내용을 살펴보자.
3. enumerable
이 속성은 열거를 가능하게 할 거냐? 안되게 할 거냐? 결정짓게 하는 속성이다.
열거? 이럴 수 있는데 코드를 보면 쉽다.
예제를 봐보자.
var obj = {}; // 빈 객체 선언
Object.defineProperty(obj, 'a', {value:'1', enumerable:true});
Object.defineProperty(obj, 'b', {value:'2', enumerable:true});
Object.defineProperty(obj, 'c', {value:'3', enumerable:true});
Object.defineProperty(obj, 'd', {value:'4', enumerable:true});
for(let i in obj){
console.log(i, obj[i]);
}
이 코드의 console.log(i. obj [i]) 는 무엇이 찍힐까?
결과는
이렇게 나온다. 예상했던 결과인가?
그렇다면 enumerable을 false로 해서 다시 결과를 찍어보자.
Object.defineProperty(obj, 'a', {value:'1', enumerable:false});
Object.defineProperty(obj, 'b', {value:'2', enumerable:false});
Object.defineProperty(obj, 'c', {value:'3', enumerable:false});
Object.defineProperty(obj, 'd', {value:'4', enumerable:false});
이렇게 전부 false로 해서 console.log를 찍어보자
어떤가?
그렇다 console.log는 아무것도 찍히지 않는다.
이렇게 obj 객체가 a~d까지 속성(프로퍼티)이 있는데 이 각각의 속성(프로퍼티)의 데이터 속성 중 enumerable을 false로 바꾸면 아무것도 안 나온다.
자 그럼 이번엔 b, d 부분만 false로 바꾸고 나머진 true로 해서 실험해보자.
Object.defineProperty(obj, 'a', {value:'1', enumerable:true});
Object.defineProperty(obj, 'b', {value:'2', enumerable:false});
Object.defineProperty(obj, 'c', {value:'3', enumerable:true});
Object.defineProperty(obj, 'd', {value:'4', enumerable:false});
결과는 어떤가?
예상했던 데로 결과 화면이다.
enumerable의 true 설정이 되어 있는 부분만 console.log의 결과가 저리 찍힌다.
즉, enumerable은 for ~ in 문 루프와 같은 특정 개체 속성 열거형에 표시되는지 여부를 제어한다.
이것도 오픈소스에서 자주 사용되어진다.
즉, 내부 소스가 어떤식으로 값을 주고받고 하는것을 console.log로 개발자가 확인하고 싶은데
저렇게 설정해두면... console.log 아무리 찍어도 값이 안나온다....
즉, 내부 소스의 값을 보여주고 싶지 않을 땐 이렇게 설정을 하면 아무것도 찍히질 않는다.
'web 언어 > HTML5 & CSS & Javascript' 카테고리의 다른 글
JS - Objects 객체에 대한 모든 것 - 4 (0) | 2022.03.10 |
---|---|
JS - Objects 객체에 대한 모든 것 - 3 (0) | 2022.03.08 |
JS - Objects 객체에 대한 모든 것 - 1 (0) | 2022.03.05 |
JS - javascript 에서의 this 를 정확히 알아보자 - 6 (바인딩 규칙 예외) (0) | 2022.03.04 |
JS - javascript 에서의 this 를 정확히 알아보자 - 5 (4가지 규칙 우선순위 ) (0) | 2022.03.04 |