JavaScript Deep Copy는 초보자에 의해 개발되었으며 경험이 많으며 종종 문제가 발생하며 JavaScript 딥 카피를 잘 이해할 수 없습니다.
딥 클론?
딥 카피의 반대는 얕은 사본입니다. 많은 초보자 들이이 느낌과 접촉 할 때 혼란스러워합니다.
딥 카피를 사용하는 이유는 무엇입니까?
대부분의 경우 변수에 값을 할당하고 메모리 주소에 값을 할당해야합니다. 그러나 참조 값 유형을 할당 할 때 메모리 영역 만 공유하여 할당시 이전 값과 일관성을 유지합니다.
구체적인 예를 참조하십시오
// var test = {a : 'a', b : 'b'}; // test2에 test2 // test2와 test2의 얕은 사본 인 var test2 = test; test2.a = 'a2'; test.a === 'a2'//삽화:
이것은 기준 값 유형 데이터가 왜 서로 영향을 미치는지 이해하는 것이 좋습니다.
성취하다
딥 카피 함수를 구현하려면 숫자 유형의 JavaScript에 대해 이야기해야합니다.
JavaScript 유형을 결정합니다
JavaScript에는 다음과 같은 기본 유형이 있습니다
유형 설명
undefinedUndErfined 유형은 값이 하나만 있습니다. 이는 변수가 할당되지 않은 경우 값입니다.
Nullnull 유형은 또한 하나의 값만 있습니다.
BooleanBoolean은 True와 False의 두 가지 값을 가지고 있습니다
문자열 텍스트 정보를 나타냅니다
번호 디지털 정보를 나타냅니다
객체 기능 함수 및 배열 배열을 포함하여 일련의 속성의 변환되지 않은 컬렉션입니다.
Typeof를 사용하여 기능과 배열을 판단하는 것은 불가능합니다. 여기서 우리는 Object.prototype.toString 메소드를 사용합니다.
[기본적으로 각 객체는 객체에서 toString () 메소드로 상속됩니다. 이 메소드가 객체 자체의 동일한 이름 메소드 또는 더 가까운 상단 프로토 타입으로 덮어 쓰기 (차단)되지 않으면 객체의 toString () 메소드가 호출되고 여기서 문자열 유형은 객체 유형을 나타냅니다] [1]
함수 유형 (obj) {var tostring = object.prototype.tostring; var map = { '[object boolean]': 'boolean', '[Object Number]': 'number', '[object string]', '[object function]', '[Object]', '[Object array]', '[Object Date]', '[Object Regexp]': 'regexp', '' ':' '' '' 'null', '[Object Object] :'object '}; 리턴 맵 [tostring.call (obj)];}딥 클론을 구현하십시오
참조되지 않은 값 유형의 숫자 값의 경우 값이 직접 할당되며 참조 된 값 유형 (개체)의 경우 다시 횡단하여 재귀 적으로 할당해야합니다.
함수 DeepClone (data) {var t = type (data), o, i, ni; if (t === 'array') {o = []; } else if (t === 'Object') {o = {}; } else {반환 데이터; } if (t === 'array') {for (i = 0, ni = data.length; i <ni; i ++) {O.push (deepclone (data [i])); } return o; } else if (t === 'Object') {for (I in data) {o [i] = 딥 클론 (data [i]); } return o; }}여기에 모두가주의를 기울여야 할 요점이 있습니다. 함수 유형의 경우 블로거가 직접 값을 할당하거나 메모리 값을 공유합니까? 이는 기능이 입력 값과 반환 값을 가진 특정 기능을 완료하는 것에 관한 것이기 때문에, 상위 수준의 서비스의 경우 비즈니스 기능을 완료하는 것이 더 많으며 실제로 기능을 깊이 복사 할 필요가 없습니다.
그러나 함수 유형을 복사하는 방법은 무엇입니까?
실제로, 블로거는 새로운 운영을 사용하는 것만 생각했지만 함수는 한 번 실행되며 실행 결과가 무엇인지 상상하지 않습니다! o (□) o! 아직 좋은 아이디어가 없습니다. 안내 해주세요!
이 시점에서 딥 카피는 거의 완료되었지만 어떤 사람들은 왜 얕은 사본이 구현되지 않았다고 생각합니까?
얕은 사본?
얕은 사본의 경우 하나의 공통 메모리 영역 만 작동하는 것으로 이해할 수 있습니다! 여기에 위험이있을 것입니다! (..*)
이 공유 데이터를 제어하지 않고 직접 작동하면 데이터 예외가 종종 발생하며 다른 부분에 의해 변경됩니다. 따라서 데이터 소스를 직접 작동시키지 않아야하며 데이터에서 두부 작업을 수행하기위한 일부 방법을 캡슐화해야합니다.
아마도 여기에는 거의 동일하지만 프론트 엔드는 JavaScript 자체뿐만 아니라 DOM, 브라우저 등을 고려합니다.
요소 유형
다음 코드를 살펴 보겠습니다. 결과에서 무엇이 반환됩니까?
Object.prototype.toString.call(document.getElementsByTagName('div')[0])
대답은 [Object htmldivelement]입니다.
때로는 DOM 요소가 저장되고 실수로 깊게 복사되면 딥 카피 함수는 요소 요소에 대한 판단이 부족합니다. 요소 요소를 판단하려면 인스턴스를 사용하여 판단하십시오. 다른 태그의 경우 Tostring은 다른 태그에 해당하는 생성자를 반환합니다.
함수 유형 (obj) {var tostring = object.prototype.tostring; var map = { '[object boolean]': 'boolean', '[Object Number]': 'number', '[object string]', '[object function]', '[Object]', '[Object array]', '[Object Date]', '[Object Regexp]': 'regexp', '' ':' '' '' 'null', '[Object Object] :'object '}; if (obj instanceof element) {return 'element'; } return map [tostring.call (obj)];}다른 방법?
jQuery의 구현
자세한 내용은 https : //github.com/jquery/jqu를 참조하십시오 ...
밑줄 구현
자세한 내용은 https : //github.com/jashkenas/...을 참조하십시오.
Lodash 구현
자세한 내용은 https : //github.com/lodash/lod를 참조하십시오.
JSON 구현
먼저 JSON.stringify를 통과 한 다음 json.parse를 통과시켜 깊은 사본을 실현할 수 있습니다. 그러나 데이터 유형은 기본 숫자 유형 만 지원합니다.
var obj = {a : 'a', b : function () {console.log ( 'b')}}}} // json.stringify가 있으면 함수가 필터링됩니다. json.stringify (obj) // "{"a ":"a "}"요약
여기서 우리는 딥 카피와 딥 카피를 구현하는 방법을 대략 요약합니다. 다른 시나리오에서는 비즈니스 시나리오를 기반으로 딥 카피가 필요한지 여부를 결정해야합니다.