>  기사  >  웹 프론트엔드  >  jQuery 데이터 캐싱 module_jquery의 진화 역사에 대한 자세한 소개

jQuery 데이터 캐싱 module_jquery의 진화 역사에 대한 자세한 소개

WBOY
WBOY원래의
2016-05-16 17:48:10926검색

데이터 캐싱 시스템은 jQuery 1.2에서 처음 도입되었습니다. 당시 해당 이벤트 시스템은 DE 마스터의 addEvent.js를 복사했지만 addEvent 구현에 결함이 있었습니다. 이는 모든 이벤트 콜백을 EventTarget에 배치했습니다. EventTarget은 창 개체이며 전역 오염을 유발합니다. 데이터 캐싱 시스템을 사용하면 이러한 두 가지 위험을 피할 수 있을 뿐만 아니라 다양한 메서드에서 생성된 중간 변수를 효과적으로 저장할 수 있으며 이러한 변수는 메서드 간의 종속성을 분리하여 다른 모듈의 메서드에 유용하게 사용될 것입니다. jQuery의 경우 이벤트 복제와 이후의 대기열 구현도 캐싱 시스템과 분리될 수 없습니다.

jQuery1.2는 핵심 모듈에 data와 RemoveData라는 두 가지 새로운 정적 메서드를 추가합니다. 말할 필요도 없이 데이터는 읽기와 쓰기를 결합한 다른 jQuery 방법과 동일합니다. jQuery의 캐싱 시스템은 모든 데이터를 $.cache에 저장한 다음 캐시 시스템을 사용해야 하는 각 요소 노드, 문서 개체 및 창 개체에 UUID를 할당합니다. UUID의 속성 이름은 임의의 사용자 정의 속성인 "jQuery"(new Date()).getTime()이고 값은 0부터 증가하는 정수입니다. 하지만 UUID는 항상 객체에 부착되어야 합니다. 해당 객체가 윈도우라면 전역 오염이 되지 않을까요? 따라서 jQuery는 내부적으로 윈도우 객체라고 판단하면 이를 windowData라는 빈 객체에 매핑합니다. UUID를 추가합니다. UUID를 사용하면 캐시 시스템에 처음 접근할 때 $.cache 객체에 빈 객체(캐시 본문)를 열어 대상 객체와 관련된 것들을 배치하게 됩니다. 이것은 은행 계좌 개설과 비슷하며 UUID의 가치는 통장입니다. RemoveData는 더 이상 저장할 필요가 없는 데이터를 삭제합니다. 결국 데이터가 삭제되고 키-값 쌍이 없어 빈 개체가 되면 jQuery는 이 개체를 $.cache에서 삭제하고 이동합니다. UUID를 제외하고.

코드 복사 코드는 다음과 같습니다.

//jQuery1.2.3
var Expando = "jQuery" (new Date()).getTime(), uuid = 0, windowData = {}
jQuery.extend({
cache: {},
data: 함수 ( elem, name, data ) {
elem = elem == window ? windowData : elem;//창 객체에 대한 특수 처리
var id = elem[ Expando ]
if ( !id ) // UUID가 아니면 새 계정을 만듭니다.
id = elem[ Expando ] = uuid
//$.cache에 개설된 계정이 없으면 먼저 계정을 엽니다.
if( name && !jQuery.cache; [ id ] )
jQuery.cache[ id ] = {};

// 세 번째 매개변수가 정의되지 않은 경우 쓰기 작업입니다.
if ( data != undefine )
jQuery.cache[ id ][ name ] = data;
//매개변수가 1개이면 캐시 객체를 반환하고, 매개변수가 2개이면 대상 데이터를 반환합니다.
return name? .cache[ id ][ 이름 ] : id
},

removeData: function( elem, name ) {
elem = elem == windowData : elem = elem[ Expando ];
if ( name ) { //대상 데이터 제거
if ( jQuery.cache[ id ] ) {
delete jQuery.cache[ id ][ name ]; = "";

for ( name in jQuery.cache[ id ] )
break
//캐시 본문이 비어 있지 않으면 이름이 다시 작성됩니다. 다시 작성되지 않은 경우 !name은 true입니다.
//따라서 이 메서드가 다시 호출되지만 이번에는 캐시 본문을 제거하기 위해 매개변수 하나만 전달됩니다.
if ( !name )
jQuery .removeData( elem );
}
} else {
//UUID를 제거하지만 IE에서 요소에 삭제를 사용하면 오류가 발생합니다.
try {
delete elem[ Expando ];
} catch(e){
if ( elem.removeAttribute )
elem.removeAttribute( Expando )
}//계정 취소
delete jQuery.cache[ id ]; }
}
})



jQuery는 체인 작업과 중앙 집중식 작업을 용이하게 하기 위해 1.2.3에서 동일한 이름의 두 가지 프로토타입 메서드 data와 RemoveData를 추가했습니다. 그리고 데이터에 getData 및 setData의 사용자 정의 이벤트 트리거 논리를 추가합니다.

1.3에서는 데이터 캐싱 시스템이 마침내 모듈 data.js(내부 개발 중 분할)로 독립되었으며 네임스페이스에 queue 및 dequeue, 네임스페이스에 queue 및 dequeue라는 두 가지 메소드 세트가 추가되었습니다. 원기. 대기열의 목적은 분명합니다. 즉, 애니메이션 모듈을 제공하기 위해 일련의 데이터를 캐시하는 것입니다. Dequeue는 데이터 세트에서 하나의 항목을 삭제하는 것입니다.




코드 복사 코드는 다음과 같습니다.

//jQuery1.3
jQuery.extend({
대기열: function( elem, type, data) {
if ( elem ){
type = (type || "fx") "queue";
  var q = jQuery.data( elem, type );
  if ( !q || jQuery.isArray(data) )//배열이 저장되어 있는지 확인하세요
q = jQuery.data( elem, type, jQuery.makeArray(data) );
else if( data )//그런 다음 이 데이터에 무언가를 추가합니다
q.push( data )
}
q 반환
},
대기열 제거: function( elem, type ){
var queue = jQuery.queue( elem, type ),
fn = queue.shift();// 그럼 하나 삭제하세요 초기에는 애니메이션 배치를 위한 콜백이었는데 삭제하면 호출이 됩니다. 내부용입니다.
if( ! type || type === "fx" )
fn = queue[0]
if( fn !== undefine )
fn .call(elem);
}
)


fx 모듈 애니메이션 메소드 호출 예:


코드 복사 코드는 다음과 같습니다.
//각각 여러 애니메이션을 병렬로 처리하고, 대기열은 여러 애니메이션을 차례로 처리합니다
 이 [ optall.queue === false ? "each" : "queue " ](function(){ /*생략*/})

요소에 사용자 정의 속성을 추가해도 문제가 발생합니다. 이 요소를 복사하면 이 속성도 복사되어 두 요소 모두 동일한 UUID 값을 가지며 데이터가 잘못 조작됩니다. jQuery의 초기 노드 복사 구현은 매우 간단합니다. 요소의 cloneNode 메소드가 이벤트를 복사하지 않으면 cloneNode를 사용하고, 그렇지 않으면 요소의 externalHTML 또는 상위 노드의 innerHTML을 사용하고 clean 메소드를 사용하여 새 요소를 구문 분석합니다. 그러나 externalHTML 및 innerHTML에는 명시적 속성이 작성되므로 정규식을 사용하여 지워야 합니다.

코드 복사 코드는 다음과 같습니다.
 //jQuery1.3.2 core.js clone method
var ret = this.map(function(){
if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
var html = this.outerHTML;
if ( !html ) {
var div = this.ownerDocument.createElement("div");
div.appendChild( this.cloneNode(true) )
html = div.innerHTML;

Return jQuery.clean([html.replace(/ jQueryd ="(?:d |null)"/g, "").replace(/^s*/, "")])[0 ];
 } else
  return this.cloneNode(true)
 }); 외부 리소스로 가져온 태그에는 오류가 발생할 수 있습니다. 이전 IE의 요소 노드는 단지 COM 래퍼이므로 리소스가 도입되면 해당 리소스의 인스턴스가 되며 엄격한 액세스 제어를 갖게 되며 일반 JS 개체처럼 마음대로 멤버를 추가할 수 없습니다. 따라서 jQuery는 이를 한 번 변경했으며 이 세 가지 태그에 대한 데이터는 캐시되지 않습니다. jQuery는 요소 노드의 레이블을 감지하는 데 사용되는 noData라는 해시를 생성했습니다.



코드 복사
코드는 다음과 같습니다. noData: { "embed": true, "객체": true,   "applet": true },
 //코드 방어
  if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
복귀
 }


jQuery 1.4에서는 $.data도 개선되어 두 번째 매개변수가 객체가 되어 여러 데이터를 쉽게 저장할 수 있습니다. UUID에 해당하는 사용자 정의 속성 Expando도 네임스페이스 아래에 배치됩니다. queue 및 dequeue 메소드가 새 모듈로 제거되었습니다.
jQuery1.43은 세 가지 개선 사항을 제공합니다.
첫 번째는 ChangeData 사용자 정의 메소드를 추가하는 것입니다. 하지만 이 방법은 매출이 없고, 제품 관리자의 나르시시즘일 뿐입니다.
요소 노드가 사용자 정의 속성 추가를 지원하는지 여부를 감지하는 논리는 acceptData라는 메소드로 구분됩니다. jQuery 팀은 객체 태그가 플래시 리소스를 로드할 때 여전히 사용자 정의 속성을 추가할 수 있다는 것을 발견했기 때문에 이 상황을 열어두기로 결정했습니다. IE가 플래시를 로드할 때 개체에 대해 classId라는 속성을 지정해야 합니다. 값은 clsid:D27CDB6E-AE6D-11cf-96B8-444553540000입니다. 따라서 데이터와 제거 데이터가 모두 사용되므로 감지 논리가 매우 복잡해집니다. 비트를 효과적으로 저장합니다.
HTML5는 "data-*"라는 새로운 캐싱 메커니즘을 추가하여 사용자 정의 속성을 무심코 추가하는 사람들의 행동에 대응합니다. 사용자가 설정한 속성이 "data-"로 시작하면 요소 노드의 데이터세트 개체에 저장됩니다. 이로 인해 사람들은 데이터를 캐시하기 위해 HTML5를 사용하거나 데이터를 저장하기 위해 jQuery의 캐싱 시스템을 사용하게 되므로 데이터 방법은 약간 쓸모 없게 됩니다. 따라서 jQuery는 프로토타입의 데이터를 향상했습니다. 사용자가 이 요소 노드에 처음으로 액세스하면 "data-"로 시작하는 모든 사용자 정의 속성을 순회합니다(이전 IE를 처리하기 위해 데이터 세트를 순회할 수 없습니다). 직접) jQuery의 캐시 본문에 넣습니다. 그런 다음 사용자가 데이터를 검색할 때 먼저 setAttribute를 사용하지 않고 캐시 시스템에서 "data-" 사용자 정의 속성에 액세스합니다. 그러나 HTML5의 캐싱 시스템은 매우 약하고 문자열만 저장할 수 있으므로(물론 순환 참조 고려 사항으로 인해) jQuery는 문자열을 "null", "false", "true"와 같은 다양한 데이터 유형으로 복원합니다. , false, true 숫자 형식을 따르는 문자열은 숫자로 변환되며, "}"로 시작하는 "{"로 끝나면 객체로 변환을 시도합니다.
코드 복사 코드는 다음과 같습니다.

 //jQuery1.43 $.fn. data
rbrace = /^(?:{.*}|[.*])$/
if ( data === undefine && this.length ) {
data = jQuery.data( this [0] , 키 );
  if ( data === 정의되지 않음 && this[0].nodeType === 1 ) {
  data = this[0].getAttribute( "data-" key ); 🎜> 
if ( typeof data === "string" ) {
try {
data = data === "true" ? true :
data === "false" false:
data === "null" ? null :
!jQuery.isNaN( data ) ? parseFloat( data ) :
rbrace.test( data ) :
data ;
 } catch( e) {}
 
  } else {
  데이터 = 정의되지 않음
  }
 }

jQuery 1.5에서는 세 가지 개선 사항도 제공됩니다. 그 당시 jQuery는 이미 1.42에서 Prototype.js를 압도했고, Matthew 효과로 인해 사용자 수가 급격히 증가했습니다. 성능 향상과 버그 수정 단계 진입(사용자가 많을수록 무료 테스터가 많아지고 테스트 범위가 넓어짐)으로 초점이 변경됩니다.
expando를 개선하세요. 원래는 시간 구분 기준이었지만 지금은 버전 번호에 난수를 더한 것입니다. 따라서 사용자는 한 페이지에 여러 버전의 jQuery를 도입할 수 있습니다.
이 데이터가 있는지 여부에 대한 논리는 hasData 메소드로 추출되며, HTML5의 "data-*" 속성도 private 메소드 dataAttr로 추출됩니다. 그것들은 모두 논리를 더 명확하게 보이도록 하기 위한 것입니다. dataAttr은 JSON.parse를 사용합니다. 왜냐하면 이 JSON은 JSON2.js에 의해 도입될 수 있고 JSON2.js에는 매우 나쁜 점이 있기 때문입니다. 즉, 일련의 기본 유형에 대해 toJSON 메서드를 추가하여 for in 루프에서 오류가 발생합니다. 빈 객체인지 확인합니다. jQuery는 처리를 위해 isEmptyDataObject 메서드를 생성해야 했습니다.
jQuery의 데이터 캐싱 시스템은 원래 이벤트 시스템을 제공하기 위해 차별화되었으며 나중에 많은 내부 모듈의 인프라가 되었습니다. 즉, 프레임워크 사용자를 위해 내부적으로 많은 변수(시스템 데이터)를 저장하지만 일단 문서에 노출되면 사용자는 비즈니스에 사용되는 데이터(사용자 데이터)를 저장하기 위해 데이터를 사용하게 됩니다. 과거에는 사용자 수가 적었기 때문에 변수 이름 충돌 가능성이 상대적으로 적었습니다. 또한 jQuery는 이러한 시스템 데이터에 대해 __class__, __change__ 또는 접미사 추가 등과 같은 흔하지 않은 이름을 신중하게 선택했습니다. , 불만사항은 접수되지 않았습니다. jQuery가 세계적 수준의 프레임워크가 되었을 때 사용자 데이터 이름이 시스템 데이터 이름을 대체하여 이벤트 시스템이나 다른 모듈이 충돌하는 일이 자주 발생했습니다. jQuery는 캐시 본문을 변환하기 시작했고, 이는 객체로 밝혀졌으며 모든 데이터가 여기에 던져졌습니다. 이제 임의의 jQuery.expando 값을 키 이름으로 사용하여 이 캐시에서 하위 개체를 엽니다. 시스템 데이터인 경우 여기에 저장됩니다. 그러나 향후 호환성을 위해 이벤트 시스템 데이터는 여전히 캐시에 직접 배치됩니다. 시스템 데이터를 구별하는 방법은 매우 간단합니다. 데이터 메소드에 4번째 매개변수를 직접 추가하면 됩니다. 세 번째 매개변수는 시스템 데이터를 삭제하기 위해 시스템 데이터를 삭제하는 경우에도 제공됩니다. 특히 운영 체제 데이터를 위한 새로운 _data 메소드도 생성되었습니다. 캐시 바디의 구조도는 다음과 같습니다.
코드 복사 코드는 다음과 같습니다.

var 캐시 = {
jQuery14312343254:{/*시스템 데이터 배치*/}
events: {/"이벤트 이름 및 해당 콜백 목록 배치"/}
/*여기에 사용자 데이터 배치* /
}

jQuery 1.7에서는 캐시 본문이 개선되었습니다. 이러한 이유로 캐시 본문을 확인할 때 해당 개선이 이루어져야 합니다. 비어 있습니다. 이제 JSON 및 데이터로 건너뛰어야 합니다. 새로운 구조는 다음과 같습니다.
코드 복사 코드는 다음과 같습니다.

var 캐시 = {
data :{/*사용자 데이터 배치*/}
/*여기에 시스템 데이터 배치*/
}

jQuery1.8은 일단 deleteIds라는 배열을 추가했습니다. UUID를 재사용했지만 수명이 짧았습니다. UUID 값은 1.8부터 더 이상 jQuery.uuid를 사용하지 않지만 대신 jQuery.guid에 의해 증분적으로 생성됩니다. jQuery 1.83 이후 크게 개선된 점은 운영 데이터의 구현이 프라이빗 메서드로 추출되었다는 점입니다. 네임스페이스와 프로토타입의 메서드는 단지 프록시일 뿐이며 사용자 데이터를 운영하기 위한 데이터, 제거 데이터 및 _data의 두 가지 메서드 그룹으로 나뉩니다. 운영 체제 데이터,_removeData. 이제 캐싱 시스템만으로도 거대한 가족이 됩니다.
jQuery 데이터 캐싱 module_jquery의 진화 역사에 대한 자세한 소개
최종 분석에서 데이터 캐싱은 대상 개체와 캐시 본체 사이에 일대일 관계를 설정한 다음 캐시 본체에서 데이터를 조작하는 것입니다. 전자. 일반 JS 객체에서 특정 속성을 추가, 삭제, 수정, 확인하는 것이 결코 어려운 일이 아니며 사용자는 어떤 트릭도 할 수 없습니다. 소프트웨어 설계 원칙의 관점에서도 이는 최상의 결과입니다(KISS 원칙 및 단일 책임 원칙에 부합).
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.