티스토리 뷰
320x100
이 글은 주니어 개발자가 쓴 글로 오류가 있을 수 있습니다.
문제가 있거나 수정이 필요한 부분은 댓글로 알려주시면 감사하겠습니다.
Mozilla 기여자가 작성한 MDN에 대해는 CC-BY-SA 2.5 라이선스에 따라 사용할 수 있습니다.
객체 변경 방지
ESMAScript 5에서는 객체를 쉽게 조작할 수 없도록 바꾸는 몇 가지 메서드를 추가했습니다. 한 번 객체를 쉽게 조작할 수 없는 객체로 바꾸고 나면 취소할 수 없습니다.
금지된 동작(아래 표 참조)을 시도할 경우, non strict mode에서는 오류 없이 해당 동작이 무시되고, strict mode에서는 에러가 발생합니다.
예제는 MDN의 예제에 주석과 코드를 일부 추가했습니다.
메서드 | 확인용 함수 | 프로퍼티 추가 | 프로퍼티 삭제 | 값 읽기 | 값 쓰기 | 프로퍼티 어트리뷰트 재정의 |
preventExtensions() | isExtensible() | X | O | O | O | O |
seal() | isSealed() | X | X | O | O | X |
freeze() | isFrozen() | X | X | O | X | X |
Object.preventExtensions() - 객체 확장 금지
프로퍼티 동적 추가와 Object.defineProperty 두 가지 방법 모두 금지합니다.
// Object.preventExtensions는 확장 불가된 객체를 반환합니다.
var obj = {};
var obj2 = Object.preventExtensions(obj);
obj === obj2; // true
// 객체는 기본으로 확장 가능입니다.
var empty = {};
Object.isExtensible(empty); // === true
// ...하지만 바뀔 수 있습니다.
Object.preventExtensions(empty);
Object.isExtensible(empty); // === false
// Object.defineProperty는 확장 불가 객체에 새 속성을 추가할 때 오류가 발생합니다.
var nonExtensible = { removable: true };
Object.preventExtensions(nonExtensible);
Object.defineProperty(nonExtensible, "new", { value: 8675309 }); // TypeError 발생
// strict mode에서, 확장 불가 객체에 새 속성을 추가하려는 시도는 TypeError가 발생합니다.
// non strict mode에서는 오류 없이 해당 동작이 무시됩니다.
function fail() {
"use strict";
nonExtensible.newProperty = "FAIL"; // TypeError 발생
}
fail();
// 확장 (__proto__(는 사라집니다. 대신 Object.getPrototypeOf를 쓰세요)를 지원하는 엔진에서만 동작합니다):
// 확장 불가 객체의 __proto__ 속성은 불변합니다.
// 프로토타입에 속성은 추가할 수 있습니다.
var fixed = Object.preventExtensions({});
fixed.__proto__ = { oh: "hai" }; // TypeError 발생
// 원시값을 넣을 경우
Object.preventExtensions(1); // (ES5 코드) TypeError: 1은 객체가 아닙니다
Object.preventExtensions(1); // (ES6 코드) 1 - 그냥 자신을 반환
Object.seal() - 객체 밀봉(유지)
객체의 [[Configurable]] 속성을 false로 만듭니다.
var obj = {
prop: function() {},
foo: 'bar'
};
// 밀봉 이전: 새 속성이 추가되고
// 기존 속성은 변경되거나 제거될 수 있음
obj.foo = 'baz';
obj.lumpy = 'woof';
delete obj.prop;
// 밀봉
var o = Object.seal(obj);
// 반환 값은 전달된 객체와 동일함
o === obj; // true
// 객체가 밀봉 상태가 됨
Object.isSealed(obj) === true; // true
// 밀봉한 객체의 속성값은 밀봉 전과 마찬가지로 변경할 수 있음
obj.foo = 'quux';
obj.foo // 'quux'
// 데이터 속성과 접근자 속성 사이의 전환은 불가
Object.defineProperty(obj, 'foo', { get: function() { return 'g'; } }); // TypeError 발생
// 속성값의 변경을 제외한 어떤 변경도 적용되지 않음 - 암묵적으로 무시됨
obj.quaxxor = 'the friendly duck'; // 추가되지 않음
delete obj.foo; // 삭제되지 않음
// strict mode에서는 이러한 시도에 대해 TypeError 발생
function fail() {
'use strict';
delete obj.foo; // 프로퍼티 삭제 - TypeError 발생
obj.sparky = 'arf'; // 프로퍼티 추가 - TypeEror 발생
}
fail();
// Object.defineProperty() 이용한 속성의 추가 - TypeError 발생
Object.defineProperty(obj, 'ohai', { value: 17 }); // TypeErorr 발생
Object.defineProperty(obj, 'foo', { value: 'eit' }); // 속성값의 변경은 가능함
Object.freeze() - 객체 동결
재귀적으로 호출하여 중첩 객체까지 동결된 불변 객체를 만들 수 있습니다.
상수 처리를 하거나 라이브러리를 만들 때 유용합니다.
JavaScript 코드에서는 성능상 이점은 없습니다. [참고 1][참고 2]
그러나 Vue에서 값이 변할 일이 없는 대용량 데이터(ex. 상품 정보)를 처리할 때, 데이터를 readnoly로 변경하여 반응성을 제한하면 성능상에 이점이 있습니다. [참고]
var obj = {
prop: function () {},
foo: "bar",
get age() {
return this._age;
},
set age(val) {
this._age = val;
},
};
// 동결 이전: 새 속성을 추가할 수 있고,
// 기존 속성을 변경하거나 제거할 수 있음
obj.foo = "baz";
obj.lumpy = "woof";
delete obj.prop;
// 동결
var o = Object.freeze(obj);
// 반환 값은 전달된 객체와 동일함
o === obj; // true
// 객체가 동결 상태가 됨
Object.isFrozen(obj); // === true
// 이제 모든 변경 시도는 암묵적으로 무시됨
obj.foo = "quux"; // 변경되지 않음
obj.quaxxor = "the friendly duck"; // 추가되지 않음
// 엄격 모드에서는 이러한 시도에 대해 TypeError 발생
function fail() {
"use strict";
obj.foo = "sparky"; // 값수정 - TypeError 발생
delete obj.foo; // 삭제 - TypeError 발생
delete obj.quaxxor; // 'quaxxor' 속성은 추가된 적이 없으므로 true 반환
obj.sparky = "arf"; // 추가 - TypeError 발생
}
fail();
// Object.defineProperty를 통한 변경 시도 - TypeError 발생
Object.defineProperty(obj, "ohai", { value: 17 });
Object.defineProperty(obj, "foo", { value: "eit" });
// 프로토타입을 변경하는 것 또한 불가함
// 아래 두 구문 모두에서 TypeError 발생
Object.setPrototype(obj, { x: 20 });
obj.__proto__ = { x: 20 };
// 원시값을 넣을 경우
Object.freeze(1); // (ES5 code) TypeError: 1 is not an object
Object.freeze(1); // (ES6 code) 1 - 그냥 자신을 반환
// 배열 동결
var a = [0];
Object.freeze(a); // 이제 배열을 수정할 수 없음
a[0] = 1; // 조용하게 실패
a.push(2); // 조용하게 실패
// 엄격 모드에서는 이런 시도에 대해 TypeError 발생
function fail() {
"use strict";
a[0] = 1;
a.push(2);
}
fail();
320x100
'Web 개발 > 자바스크립트' 카테고리의 다른 글
Node.js 파일 시스템 관련 npm package 정리 (0) | 2022.02.24 |
---|---|
JavaScript | Observer 시리즈 4탄(완) - PerformanceObserver (0) | 2021.07.02 |
JavaScript | Observer 시리즈 3탄 - IntersectionObserver (0) | 2021.06.25 |
Jest 설정 옵션(Jest Configuring Options) (0) | 2021.06.21 |
JavaScript | Observer 시리즈 2탄 - ResizeObserver (0) | 2021.06.18 |
댓글
최근에 올라온 글
TAG
- mkdirp
- JavaScript
- node cp -r
- 페이지 특정 위치 link
- node fs
- node rm -rf
- 자바스크립트
- make-dir
- ELIFECYCLE
- 스터디
- ModuleParseError: Module parse failed: Unexpected token
- 인가
- node mkdir -p
- fs-extra
- 스토리북 에러
- Storybook Error
- 인증
- errno 253
- file opener preference
- node file package
- 웹팩 에러
- ECONNRESET
- jest
- rimraf
- sass
- Webpack Error
- createAction
- javascript event
- external editor
- 프로그래머스