JavaScript에서 객체 변이 소개

프로그래밍에서 객체 변형은 객체가 생성된 후 그 상태나 데이터가 변형됨을 의미합니다. 즉, JavaScript에서 객체의 속성을 변경하는 작업은 객체 변형(object mutation)으로 알려져 있습니다. 객체 변형은 객체의 값을 직접적으로 변경하므로, 여러 작업이 동시에 객체를 읽거나 쓰려고 할 때 특히 어려움을 초래합니다.

이 기사는 JavaScript에서 객체 변형에 대한 논의를 관련 코드 예제와 함께 제공합니다.

JavaScript의 데이터 유형

데이터 유형은 변수나 객체가 가질 수 있는 데이터의 종류를 나타냅니다. JavaScript는 두 가지 뚜렷한 데이터 유형 범주인 원시형과 사용자 정의형 또는 참조형을 지원합니다.

원시 데이터 유형

JavaScript에서 모든 원시 데이터 유형은 본질적으로 불변(immutable)입니다. 즉, 생성된 후에는 변경할 수 없습니다. 숫자, 불리언, 문자열, 빅인트, 정의되지 않음, 널, 심볼, 객체 등이 원시 유형의 예입니다.

사용자 정의형 또는 참조 데이터 유형

사용자 정의 데이터 유형 또는 참조 데이터 유형은 원시 유형 또는 원시와 사용자 정의 유형의 조합을 사용하여 생성된 객체입니다. 사용자 정의형 또는 참조형의 전형적인 예로는 객체와 배열이 있습니다.

JavaScript에서 변수 할당 및 재할당 방법

원시 타입 변수를 원시 타입 변수에 할당할 때, 두 변수는 유사한 값을 가지지만 서로 다른 저장 위치에 저장됩니다. 예를 들어, 두 변수 varAvarB가 있고, 다음과 같이 하나의 변수를 다른 변수에 할당한다고 가정해 보겠습니다:

JavaScript

 

앞서 언급한 코드를 실행하면 숫자 100이 콘솔에 표시됩니다. 이제 두 변수 중 하나의 값(예: varB)을 다음과 같이 변경합니다.

JavaScript

 

변수 varB의 값이 500으로 변경된 것을 주목하세요. varA의 값을 출력하면 여전히 100이 표시됩니다. 이는 varAvarB가 서로 다른 메모리 위치에 저장되기 때문입니다. 따라서 둘 중 하나를 변경하더라도 다른 변수에는 새로운 값이나 변경된 값이 반영되지 않습니다.

JavaScript에서 객체 변형이란 무엇인가요?

JavaScript에서 객체의 데이터 타입은 두 가지 범주 중 하나에 속할 수 있습니다: 원시 또는 비원시. 원시 타입은 불변성이 있으며, 즉 생성한 후에는 변경할 수 없고, 비원시 타입(예: 객체와 배열)은 변경할 수 있습니다. 객체는 항상 그 값을 변경할 수 있게 허용합니다. 따라서 새로운 인스턴스를 생성하지 않고도 변경 가능한 타입의 필드 상태를 변경할 수 있습니다.

객체 변형은 다음과 같은 여러 문제를 일으킬 수 있습니다:

  • 변형된 객체는 종종 동시성과 스레드 안전성 문제로 인해 경쟁 조건을 초래할 수 있습니다.
  • 돌연변이는 예측 가능성 및 스레드 안전 문제로 인해 소스 코드에 복잡성을 도입할 수 있습니다
  • 돌연변이는 종종 응용 프로그램의 소스 코드에서 식별하기 어려운 버그를 야기할 수 있습니다
  • 돌연변이는 테스트 및 디버깅을 어렵게 만들며, 돌연변화를 활용하는 코드를 추적하는 것이 어려워집니다

객체 돌연변이를 보여주는 코드 예제

객체 돌연변이는 다음 시나리오 중 어디에서든 발생할 수 있습니다

  • 속성을 추가, 편집 또는 제거하는 경우
  • 돌연변이를 나타낼 수 있는 메서드 사용

객체의 속성을 직접 또는 간접적으로 변경할 때, 객체를 돌연변이시킨다고 볼 수 있습니다. 다음 코드 스니펫은 속성을 변경하여 객체를 돌연변이시키는 방법을 보여줍니다

JavaScript

 

위의 코드 조각에서는 author라는 이름의 객체를 생성하고, idname이라는 두 속성을 포함합니다. id 속성은 저자 레코드의 id를 저장하는 데 사용되고, name 속성은 저자의 이름을 저장합니다. id 속성에 관련된 값을 변경하여 author 객체를 돌연변이시키는 방법을 주목하세요. 다음으로 author 객체에 city라는 새 속성을 추가하고 속성에 값을 할당합니다

위의 코드 조각을 실행하면, author 객체의 속성과 값이 아래와 같이 표시됩니다:

JavaScript

 

JavaScript에서 객체를 함수에 전달하거나 변수에 할당할 때, 본질적으로 객체의 참조를 전달하는 것이지 복사본을 전달하는 것이 아닙니다. 이는 객체를 전달하거나 변수에 할당하여 생성된 새로운 객체에 대한 변경 사항이 실제 객체의 모든 참조에 적용된다는 것을 의미합니다.

다음 코드는 JavaScript에서 객체를 생성하고 변수가 할당되는 방법을 보여줍니다.

JavaScript

 

앞서 언급한 코드에서 객체 objAobjB에 할당되며, objA의 pincode 속성 값이 변경됩니다. 즉, 객체 objA가 변형됩니다. 프로그램을 실행하면 다음 데이터가 표시됩니다.

JavaScript

 

pincode 속성의 값이 변경되었다는 점에 유의하세요.

JavaScript에서 객체 변형 방지

JavaScript에서 다음과 같은 여러 방법으로 변형을 방지할 수 있습니다:

  • Object.assign() 메서드나 전개 연산자(…)를 이용한 객체 복제
  • Object.seal() 메서드를 사용하여 객체의 속성을 추가하거나 삭제하는 것을 방지
  • Object.freeze() 메서드를 사용하여 객체의 속성을 추가, 편집 또는 삭제하는 것을 방지

클로닝 사용

전개 연산자를 사용하여 JavaScript에서 객체를 클로닝하는 방법을 보여주는 코드를 참조하세요.

JavaScript

 

여기서 클론된 객체의 이름은 clonedObj이며, 원래 객체 originalObj와 동일합니다. 따라서 이 두 객체의 두 속성 값을 표시하면 결과는 동일할 것입니다.

이제 클론된 객체 clonedObj의 속성 중 하나의 값을 아래 제공된 코드 조각처럼 원하는 값으로 변경하세요.

Plain Text

 

다음 코드를 작성하여 두 객체 originalObjclonedObj에 해당하는 x 속성의 값을 표시하세요.

Plain Text

 

프로그램을 실행하면 원래 객체의 x 속성 값은 변경되지 않음을 알 수 있습니다. 값은 아래와 같이 콘솔에 표시됩니다:

Plain Text

 

Object.freeze() 메서드 사용하기

Object.freeze() 메서드는 객체의 속성을 변경할 수 없도록 하여 객체를 불변으로 만들 수 있습니다.

JavaScript

 

앞서 제시된 코드를 실행하면 결과는 다음과 유사할 것입니다:

JavaScript

 

출력에서 볼 수 있듯이, city, state 및 pincode 속성에 값을 할당했음에도 불구하고 아무런 영향이 없습니다. 따라서 객체의 속성에 포함된 데이터에는 변화가 없습니다.

Object.seal() 메서드 사용하기

JavaScript에서 객체의 변형을 방지하기 위해 Object.seal() 메서드를 사용할 수도 있습니다. 이 메서드를 사용하면 기존 속성의 값을 변경할 수 있지만, 객체의 속성을 수정하거나 삭제할 수는 없습니다. 다음 코드 예제가 이를 설명합니다:

JavaScript

 

앞서 언급된 코드 스니펫에서는 ‘author’라는 객체의 속성을 수정하는 것은 허용되지만, 객체의 속성을 추가하거나 삭제하는 것은 허용되지 않습니다. 프로그램을 실행하면 수정된 속성의 값이 결과에 반영되지만, 속성을 추가하거나 삭제하는 문이 무시됩니다. 콘솔에서 출력 결과가 어떻게 나타날지 여기에 표시되어 있습니다:

JavaScript

 

Object.defineProperty() 메서드 사용

JavaScript에서 개별 속성의 가변성을 제어하기 위해 Object.defineProperty() 메서드를 활용할 수도 있습니다. 다음 코드 스니펫은 이 방법을 사용하여 가변성이 제한된 속성에 포함된 값의 변경을 허용하지 않는 방법을 보여줍니다.

JavaScript

 

앞서 언급된 코드 조각을 실행하면 숫자 3이 콘솔에 표시됩니다.

주요 포인트

  • JavaScript는 기본(primitives) 및 객체(objects) 두 가지 distinct한 범주로 객체 유형을 분류합니다.
  • 객체 변이(object mutation)란 객체가 생성된 후에 변경되거나 변하는 작업을 의미합니다.
  • 숫자 등과 같은 기본 값은 변경할 수 없지만 객체는 생성된 후에 항상 변경할 수 있습니다.
  • JavaScript에서 문자열은 변경할 수 없기 때문에 생성된 후에 수정할 수 없습니다.
  • 변이 자체는 그다지 좋지 않지만, 응용 프로그램의 버그를 줄이기 위해 신중하게 관리해야 합니다.
  • 권장 사항을 따르고 변경할 수 없는 데이터 구조를 활용하여 JavaScript의 변이를 줄이거나 제거할 수 있습니다.

Source:
https://dzone.com/articles/an-introduction-to-object-mutation-in-javascript