WeakMap 및 WeakSet: JavaScript 약한 참조 이해

작성자Coner Murphy✏️
언어의 설계 방식 때문에 JavaScript에서 약한 참조를 자주 사용하지 않습니다.그러나 개발자가 추가 데이터를 저장해야 하고 메모리 사용 상황을 자동으로 관리해야 하는 등 중요한 것으로 증명될 수도 있다.
이 글은 자바스크립트의 약한 인용과 언어의 두 대상을 어떻게 활용하여 사용하는지 알아보겠습니다. WeakMapWeakSet.

이해하다


먼저 JavaScript의 일반 참조 또는 고정 참조가 무엇인지 살펴보겠습니다.가장 간단한 정의에서, 강력한 인용은 대상을 메모리에 저장하는 인용이다.이제 실천 과정에서 이 점을 살펴보고 우리가 이야기하고 있는 내용을 살펴보자.
let dog = { name: "badger" };

const pets = [dog];

dog = null;

console.log(pets); // [{ name: "badger" }]
변수를 대상으로 만들면, 우리는 이 대상을 하나의 그룹에 넣고, 그 값을 null 로 설정해서 우리가 만든 변수에서 원시 대상에 대한 인용을 삭제할 수 있습니다.dog 변수를 통해 대상에 접근할 수 없습니다. pets 수조와 대상 사이에 강력한 인용이 있기 때문에 대상은 메모리에 저장되어 있고 pets[0]를 통해 접근할 수 있습니다.
쓰레기 수집을 통해 메모리에서 대상을 삭제하는 것을 방지하기 위해 강력 인용한다는 얘기다.

약한 인용을 이해하다


간단하게 말하면 약한 인용은 한 대상에 대한 인용이다. 만약 그것이 메모리에서 그 대상에 대한 유일한 인용이라면 쓰레기 수집을 막지 못할 것이다.
일반 인용(강인용으로 여겨지는)은 대상의 쓰레기 수집을 막을 것이다. 설령 그것이 유일하게 대상을 인용하더라도.이것은 약한 인용의 상황이 아니다.
이 이론을 앞의 강인용 예에 응용하고 약인용의 상하문에 응용합시다.현재 WeakMap의 사용을 무시합니다.우리는 본문 뒤에서 이 점을 더욱 깊이 있게 해석할 것이다.이제 약한 인용 행위를 살펴보자.
let pets = new WeakMap();
let dog = { name: "badger" };

pets.set(dog, "okay");
console.log(pets); // WeakMap{ {...} -> "Okay" } <= dog set to the WeakMap

dog = null; // Overwrite the reference to the object
console.log(pets); // WeakMap(0) <= dog has been garbage collected.
WeakMap와 그에 덧붙인 약한 인용을 이용하여 우리는 두 가지 유형의 인용 간의 차이를 볼 수 있다.원시dog 대상에 대한 강(정상) 인용은 여전히 존재하지만 dog 대상은 WeakMap 대상에 존재하기 때문에 우리는 문제 없이 접근할 수 있다.
그러나 우리가 변수를 dog에 다시 지정해서 원시 null 대상에 대한 인용을 덮어쓸 때 메모리에서 원시 대상에 대한 유일한 인용은 우리가 만든 WeakMap 대상에서 나온 약한 인용이다.
약한 인용이기 때문에 쓰레기 수집을 막지 못한다.이것은 the JavaScript engine이 쓰레기 수집 과정을 다시 실행할 때 dog 대상은 메모리와 우리가 분배한 WeakMap 대상에서 삭제된다는 것을 의미한다.
주의해야 할 관건적인 차이점은 강제 인용은 대상이 쓰레기 수집을 막고 약한 인용은 하지 않는다는 것이다.
기본적으로 JavaScript는 모든 참조에 강한 참조를 사용하며 약한 참조를 사용하는 유일한 방법은 WeakMap 또는 WeakSet를 사용하는 것입니다.

쓰레기 수집은 무엇입니까?


쓰레기 수집은 상세하고 복잡한 주제이지만 인용을 논의할 때 이해하는 것이 중요하다.
Garage collection is an automated process controlled by the JavaScript engine . 하나의 값이 접근할 수 있을 때, 그것은 쓰레기가 수집되지 않고 메모리에 저장될 수 있으며, 두 가지 방법으로 하나의 값이 접근할 수 있다고 여길 수 있다.
우선, 그것들은 기본적인 도달 가능한 값 집합의 일부분이다. 예를 들어 전역 변수, 현재 실행되고 있는 함수와 국부 변수/매개 변수, 그리고 더 많은 내부 값이다.
다른 하나는 인용이나 인용 체인을 통해 뿌리에서 어떤 값을 얻는 것이다.예를 들어 우리가 전역 변수에 대상을 만든다고 가정하면이는 전반적인 공간을 통해 도달할 수 있기 때문에 도달할 수 있는 것으로 여겨진다.
현재, 만약 우리가 다른 대상을 만들고, 우리가 만든 전역 대상에서 그것을 인용한다면, 그것도 전역 대상을 통해 인용되기 때문에 접근할 수 있다.
그러나 전역 대상을 null 로 설정해서 제거하면, 인용으로 접근한 대상은 갑자기 접근할 수 없기 때문에 쓰레기로 수집됩니다.
이것은 JavaScript의 기본값이기 때문에 인용이 강한 인용입니다.그러나 이것은 약한 인용에도 적용된다. 유일한 예외는 대상에 대한 유일한 인용이 약한 인용이라면 쓰레기 수집을 막지 않고 대상이 삭제된다는 것이다.
이것은 쓰레기 수집 작업 원리에 대한 고급 개술이다.본질적으로 어떤 내용에 접근할 수 없으면 다른 위치에서 사용할 수 있도록 메모리에서 삭제됩니다.

집합 vs. 약한 집합


Per MDN, Set의 대상은 값의 집합이다. 집합 중의 원소를 삽입 순서대로 옮겨다닐 수 있다. Set의 값은 한 번만 나타날 수 있다. Set의 집합 중 유일한 것이다.
간단하게 말하면 aSet는 유일한 값만 포함하는 수조와 같지만, 우리는 여전히 수조처럼 forloops와.forEach 등의 방법을 사용하여 이를 교체할 수 있다.Set와 유사하게 WeakSet는 서로 유일하지만 WeakSet는 대상만 저장할 수 있고 문자열이나 숫자 등 어떠한 종류의 값도 포함할 수 없기 때문이다.
결국 말 그대로 WeakSets가 약하다는 것은 약한 인용을 사용한다는 뜻이다.
또한 약한 인용을 사용하는 흥미로운 부작용 중 하나WeakSet는 일일이 다 들 수 없다는 점도 주목할 만하다.이것은 집합에 현재 대상의 목록이 저장되어 있지 않기 때문에 그 안에 포함된 항목을 순환할 수 없다는 것을 의미한다.그것들은 약한 인용으로 언제든지 삭제할 수 있습니다.
다음은 사용 중WeakSet의 예와 우리가 호출할 수 있는 방법입니다.
const pets = new WeakSet();
const cat = {name: "fluffy"};
const dog = {name: "badger"};

pets.add(cat);
pets.add(dog);

pets.has(cat);    // true
pets.has(dog);    // true

pets.delete(cat); // removes cat from the set
pets.has(cat);    // false, cat has been removed
pets.has(dog);    // true, dog is retained

지도 vs. WeakMap


According to MDN, "Map 대상은 키 값 쌍을 저장하고 키의 원래 삽입 순서를 기억합니다. 모든 값(대상과 원어 값)은 키나 값으로 사용할 수 있습니다."
이것은 Map가 하나의 대상처럼 우리는 키 값 쌍을 저장하고 키를 통해 Map에 포함된 값을 접근할 수 있다는 것을 의미한다.그러나 a standard object in JavaScript와 달리 우리는 .get() 방법을 사용하여 이 값에 접근해야 한다.
aMap와 비교하면 aWeakMap는 기본적으로 같지만 그가 가지고 있는 인용은 약한 인용이다. 이것은 인용한 값이 다른 곳에서 강제로 인용되지 않으면 쓰레기 수집이 이 값을 삭제하는 것을 막지 못한다는 것을 의미한다.
이 밖에 WeakMap 같은 부작용, 즉 약한 인용으로 일일이 열거할 수 없다는 것이다.
마지막으로, 우리는 대상을 키로 사용해야 하지만, 값은 문자열이나 숫자와 같은 임의의 값일 수 있다.다음은 사용 예제WeakMaps와 우리가 사용할 수 있는 방법입니다.
const wm1 = new WeakMap();
const wm2 = new WeakMap();

const obj1 = {};
const obj2 = window;

wm1.set(obj1, 100);
wm1.set(obj2, 'Hello');
wm2.set(obj1, obj2); // You can set the value to be anything including an object or function
wm2.set(obj2, undefined); // Or, undefined
wm1.set(wm2, wm1); // Or, even a WeakMap itself

wm1.get(obj1); // 100

wm1.has(obj1); // true
wm1.delete(obj1);
wm1.has(obj1); // false

결론


끝나기 전에 약한 인용의 잠재적인 용례와 본고에서 소개한 두 대상을 고려해 봅시다.
추가 데이터를 임시로 저장하고 메모리를 정리하거나 대상을 삭제하는 것을 걱정하지 않으려면 약한 인용을 사용하는 것이 구원의 별입니다.
그러나 JavaScriptWeakMaps, WeakSets를 자주 사용할 필요는 없고, 약한 인용을 자주 사용할 필요도 없습니다.
간혹 이해하기 쉽고 기본 지식을 습득하기 쉽지만 대다수 상황에서는 정상적(강) 참고를 사용한다.
나는 이 자바스크립트의 약한 인용에 관한 문장이 너에게 도움이 되기를 바란다. 만약 네가 정말 이렇게 한다면, 나는 여기에 유용하고 조작 가능한 기교와 자바스크립트 생태계의 내용을 발표할 것이다.

LogRocket: 컨텍스트를 이해하여 JavaScript 오류를 쉽게 디버깅할 수 있습니다.


코드를 디버깅하는 것은 항상 무미건조한 작업이다.하지만 자신의 잘못을 알면 알수록 바로잡기 쉽다.
LogRocket 이러한 오류를 새롭고 독특한 방식으로 이해할 수 있습니다.Dell의 프런트엔드 모니터링 솔루션은 사용자와 JavaScript 프런트엔드의 상호 작용을 추적하여 사용자가 실수로 인한 문제를 정확하게 파악할 수 있도록 합니다.

LogRocket 레코드 콘솔 로그, 페이지 로드 시간, 스택 추적, 제목 + 본문이 있는 느린 네트워크 요청/응답, 브라우저 메타데이터 및 사용자 정의 로그.JavaScript 코드의 영향을 이해하는 것은 더 이상 쉬운 일이 아닙니다!
Try it for free .

좋은 웹페이지 즐겨찾기