개발공부

재우스 AI 후속 패치 - AI 메이커 추가, 깊은 복사 오류 수정

카로루딘 2024. 8. 21. 20:51

패턴을 복제하는 코드의 로직은 다음과 같다.

 

1. 복제 버튼을 누르면 PatternButton 스크립트의 deleteDupleQueue(이하 딜리듀플)가 발동한다.

2. 딜리듀플은 삭제 버튼과 호환되어

 

위 로직대로 발동한다.

3. 복사 버튼을 눈렀다면 splice 버튼으로 복사할 인덱스 앞에 새 패턴을 생성한다.

 

여기까지는 일반적인 복사 패턴이다. 그런데 여기서 복사한 패턴들은 이름이 다른데 list 부분에서 얕은 복사가 이뤄지고 있다는 것이 1차적인 판단이었다. 쳇GPT한테 물어보니

 

JavaScript에서 객체나 배열을 `...`(스프레드 연산자)를 사용하여 복사할 때, 복사는 얕은 복사(shallow copy)만 이루어집니다. 이는 배열의 첫 번째 레벨까지만 복사되고, 그 안에 있는 배열이나 객체는 참조로 남게 된다는 뜻입니다.
### 예시를 들어 설명하겠습니다:
```javascript
let asd = [[['a', 'b', 'c'],['d', 'e', 'f']],[['g', 'h', 'i'],['j', 'k', 'l']];
let abc = [...asd];
```
위의 코드에서 `abc`는 `asd`의 첫 번째 레벨 배열을 복사합니다. 이 과정에서 얕은 복사가 이루어지므로, `abc`는 `asd`의 첫 번째 레벨 배열에 대한 새로운 배열을 가리키게 되지만, 그 안에 있는 두 번째 및 세 번째 레벨의 배열들은 원래 `asd`의 배열을 참조하게 됩니다.
즉, 다음과 같은 구조가 됩니다:
- `abc[0]`와 `asd[0]`는 서로 다른 배열입니다.
- 그러나 `abc[0][0]`와 `asd[0][0]`는 같은 배열을 참조합니다.
- 마찬가지로 `abc[0][0][0]`와 `asd[0][0][0]`도 같은 문자열 `'a'`를 참조합니다.
### 요약:
- **1차 레벨:** 깊은 복사 (새로운 배열 생성)
- **2차 레벨 이후:** 얕은 복사 (기존 배열 참조)
따라서, `let abc = [...asd]`는 3차원 배열의 첫 번째 레벨만 깊은 복사가 이루어지며, 그 안의 배열들은 여전히 원본 배열인 `asd`와 참조 관계를 유지합니다. 
만약 전체 구조에 대해 깊은 복사를 하고 싶다면, JSON 방법을 사용하거나 재귀적으로 배열을 복사하는 방법을 사용해야 합니다.

 

라고 한다. 그러면 깊은 복사를 "깊이"하려면 일반적인 스프레드 연산자로는 안된다는 얘기인데.....

 

1차 해결법 - lodash 사용

과정 - 간단하다. 그냥 let delVal을 lodash로 고치는 것이다.

결과 - 실패다. 여전히 복사한 패턴들은 입을 맞춰 "내가 범인이오!" 하고 합창을 하고 있다.

분석 - 복제말고 다른 부분에서 문제가 발생하는 것이다.

 

2차 해결법 - 로직 추적

과정 - 변경된 패턴 내용을 적용하는 다른 함수를 추적한다. 

 

 

여기서도 lodash로 딥카피를 하고 있다. 그래서  콘솔 로그를 찍어보니 이미 여기로 넘어오는 시점에서 전부 복사가 되어 있었다. 그러면 아직도 얕은 복사가 진행되고 있다는 뜻인데....다시 한번 딜리듀플을 손봐야겠다.

결과 - 챗GPT도 깊은 복사는 잘 모른다

 

혹시나 싶어 list 부분을 스프레드 연산자로 lodash로 딥카피한 걸 또 파헤쳐서 딥카피했다. 그러니 드디어 정상작동이 된다!

분석 - lodash의 딥카피 기능은 우리가 생각하는 것처럼 완전 깊은 형태는 복사하지 못하는 것 같다....

 

 

 

 

다음으로 해결할 것은 반응형 웹 디자인이다.