찾다

 >  Q&A  >  본문

JavaScript 개체를 올바르게 복제하는 방법은 무엇입니까?

<p><code>x</code> 개체가 있습니다. <code>y</code>에 대한 변경 사항이 <code>x</code>를 수정하지 않도록 이를 <code>y</code> 개체로 복사하고 싶습니다. 내장된 JavaScript 객체에서 파생된 객체를 복사하면 원치 않는 추가 속성이 생성된다는 것을 깨달았습니다. 내 자신의 텍스트 구성 개체 중 하나를 복사하고 있으므로 이는 문제가 되지 않습니다. </p> <p>JavaScript 개체를 올바르게 복제하는 방법은 무엇입니까? </p>
P粉334721359P粉334721359488일 전524

모든 응답(2)나는 대답할 것이다

  • P粉691958181

    P粉6919581812023-08-24 09:44:45

    개체에서 날짜, 함수, 정의되지 않음, regExp 또는 Infinity를 사용하지 않는 경우 매우 간단한 줄은 JSON.parse(JSON.stringify(object))< /代码>:

    입니다.

    으아아아

    이것은 객체, 배열, 문자열, 부울 및 숫자를 포함한 모든 유형의 객체에 작동합니다.

    작업자와 메시지를 게시할 때 사용되는 구조적 복제 알고리즘 브라우저 에 대한 이 기사 도 참조하세요. 또한 심층 복제 기능도 포함되어 있습니다.

    회신하다
    0
  • P粉122932466

    P粉1229324662023-08-24 00:44:32

    2022년 업데이트

    Structured Cloning이라는 새로운 JS 표준이 있습니다. 다양한 브라우저에서 작동합니다(사용할 수 있습니다 참조).

    으아아아

    오래된 답변

    JavaScript의 모든 개체에 대해 이 작업을 수행하는 것은 간단하거나 간단하지 않습니다. 새 인스턴스에 복사되는 대신 프로토타입에 남아 있어야 하는 개체의 프로토타입에서 속성을 잘못 가져오는 문제에 직면하게 됩니다. 예를 들어 Object.prototype 添加一个 clone 方法(如某些答案所述),则需要显式跳过该属性。但是,如果在 Object.prototype 或其他中间原型中添加了您不知道的其他附加方法怎么办?在这种情况下,您将复制不应该复制的属性,因此您需要使用 hasOwnProperty 메소드를 사용하려는 경우입니다.

    열거 불가능한 속성 외에도 숨겨진 속성이 있는 개체를 복사하려고 하면 더 까다로운 문제에 직면하게 됩니다. 예를 들어 prototype 是函数的隐藏属性。此外,对象的原型是通过属性 __proto__ 에서 참조하는 이 속성은 숨겨져 있으며 소스 개체의 속성을 반복하는 for/in 루프에 의해 복사되지 않습니다. 내 생각에 __proto__는 Firefox의 JavaScript 인터프리터에만 해당될 수 있고 다른 브라우저에서는 다를 수 있지만 아이디어를 얻으실 수 있습니다. 모든 것이 열거 가능한 것은 아닙니다. 숨겨진 속성의 이름을 알고 있다면 복사할 수 있지만 자동으로 검색할 수 있는 방법은 없습니다.

    우아한 솔루션을 찾는 데 있어 또 다른 장애물은 프로토타입 상속을 올바르게 설정하는 문제입니다. 소스 객체의 프로토타입이 Object,则只需使用 {} 创建一个新的通用对象即可,但如果源对象的原型是 Object 的某个后代code>,那么您将丢失该原型中使用 hasOwnProperty 필터가 건너뛰는 다른 멤버이거나 프로토타입에 있지만 처음에 열거할 수 없었던 다른 멤버인 경우. 한 가지 해결책은 소스 객체의 생성자 속성을 호출하여 초기 복사 객체를 가져온 다음 속성을 복사하는 것일 수 있지만 여전히 열거할 수 없는 속성은 얻지 못합니다. 예를 들어, Date 개체는 데이터를 숨겨진 멤버로 저장합니다.

    으아아아

    d1 的日期字符串将比 d2 晚 5 秒。使一个 Date 与另一个相同的方法是调用 setTime 方法,但这是特定于 Dated1의 날짜 문자열은

    d2
    보다 5초 늦습니다. 🎜Date를 다른 것과 동일하게 만드는 방법은 🎜setTime 메서드를 호출하는 것이지만 이는 🎜Date 클래스에만 해당됩니다. 나는 이 문제에 대한 완벽하고 보편적인 해결책이 있다고 생각하지 않습니다. 비록 제가 틀렸다는 것이 기쁘지만요! 🎜

    일반 딥 카피를 구현해야 했을 때, 일반 ObjectArrayDate、<代码>字符串、<代码>数字或<代码>布尔。最后 3 种类型是不可变的,因此我可以执行浅复制而不用担心它会发生变化。我进一步假设 ObjectArray만 복사하면 되고 여기에 포함된 모든 요소도 해당 목록의 6가지 단순 유형 중 하나가 될 것이라고 가정하여 타협하게 되었습니다. 이는 다음과 같은 코드로 수행할 수 있습니다:

    으아아아

    객체와 배열의 데이터가 트리 구조를 형성하는 한, 위의 함수는 제가 언급한 6가지 단순 유형에 충분합니다. 즉, 개체의 동일한 데이터는 두 번 이상 참조되지 않습니다. 예:

    으아아아

    JavaScript 개체를 처리하지는 않지만, 던지는 모든 개체에서만 작동할 것이라고 생각하지 않는 한 다양한 목적으로 충분할 것입니다.

    회신하다
    0
  • 취소회신하다