프로토타입 메서드 맵은 반환된 데이터를 반환하기 전에 다른 프로토타입 메서드인 pushStack 메서드로 처리해야 한다는 점을 제외하면 각각과 유사하며 동일한 이름의 정적 메서드를 호출합니다.
map: function( callback ) { return this.pushStack( jQuery.map(this, function( elem, i ) { return callback.call( elem, i, elem ); })); },
이 글은 주로 static map 방식을 분석하며, pushStack에 대해서는 다음 에세이에서 분석하겠습니다.
먼저 지도(매뉴얼 콘텐츠) 사용법을 이해하세요$.map은 한 배열의 요소를 다른 배열로 변환합니다.
변환 함수는 배열 요소별로 매개변수로 호출되며, 변환 함수에는 변환되는 요소를 나타내는 매개변수가 전달됩니다.
변환 함수는 변환된 값, null(배열에서 항목 제거) 또는 원래 배열로 확장된 값이 포함된 배열을 반환할 수 있습니다.
매개변수
arrayOrObject,callbackArray/Object,FunctionV1.6
arrayOrObject: 배열 또는 개체입니다.
함수는 어떤 값이든 반환할 수 있습니다.
또는 이 함수를 문자열로 설정할 수 있으며, 문자열로 설정하면 "람다 형식"(약식?)으로 처리됩니다. 여기서 a는 배열 요소를 나타냅니다.
예를 들어 "a * a"는 "function(a){ return a * a; }"를 나타냅니다.
예 1:
//将原数组中每个元素加 4 转换为一个新数组。 //jQuery 代码: $.map( [0,1,2], function(n){ return n + 4; }); //结果: [4, 5, 6]
//原数组中大于 0 的元素加 1 ,否则删除。 //jQuery 代码: $.map( [0,1,2], function(n){ return n > 0 ? n + 1 : null; }); //结果: [2, 3]
//原数组中每个元素扩展为一个包含其本身和其值加 1 的数组,并转换为一个新数组 //jQuery 代码: $.map( [0,1,2], function(n){ return [ n, n + 1 ]; }); //结果: [0, 1, 1, 2, 2, 3]
예를 들어, Each()는 원래 배열을 반환하고 새 배열을 생성하지 않는 반면, map은 새 배열을 생성합니다. 이는 각 순회가 현재 배열 또는 개체 값을 가리키고 map이 창을 가리킨다는 것을 의미합니다. 소스 코드는
과 같은 객체 가장을 사용하지 않습니다.
예:
var items = [1,2,3,4]; $.each(items, function() { alert('this is ' + this); }); var newItems = $.map(items, function(i) { return i + 1; }); // newItems is [2,3,4,5] //使用each时,改变的还是原来的items数组,而使用map时,不改变items,只是新建一个新的数组。 var items = [0,1,2,3,4,5,6,7,8,9]; var itemsLessThanEqualFive = $.map(items, function(i) { // removes all items > 5 if (i > 5) return null; return i; }); // itemsLessThanEqualFive = [0,1,2,3,4,5]
// arg is for internal usage only map: function( elems, callback, arg ) { var value, key, ret = [], i = 0, length = elems.length, // jquery objects are treated as arrays isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; // Go through the array, translating each of the items to their if ( isArray ) { for ( ; i < length; i++ ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret[ ret.length ] = value; } } // Go through every key on the object, } else { for ( key in elems ) { value = callback( elems[ key ], key, arg ); if ( value != null ) { ret[ ret.length ] = value; } } } // Flatten any nested arrays return ret.concat.apply( [], ret ); },
을 분석할 수 있습니다.
먼저 괄호로 계산한 다음 length !== undefine 및 typeof length === "number를 결과에 추가합니다. 이 두 가지 필수 조건의 최종 결과는 jQuery의 요소 인스턴스와 논리적으로 OR됩니다. 간단히 말하면 isArray입니다. 실제 상황은 다음과 같습니다.1. jQuery의 elems 인스턴스는 true, 즉 jquery 객체입니다
2. 길이 !== 정의되지 않음 && 길이 === "숫자" 및 길이 > 0 && elems[ 0 ] && elems[ length -1 ] ) || elems) 이 셋 중 적어도 하나는 성립합니다
3가지 작은 상황으로 나눌 수 있습니다
length가 존재하고 숫자이며, 순회할 배열 또는 배열 유사 객체의 길이 속성이 0보다 큽니다. 이는 jquery 객체, domList 객체와 같이 순회할 수 있음을 보장합니다. 등
길이가 존재하고 숫자이며 길이 속성이 0입니다. 0이면 상관없으며 순회되지 않습니다.
길이가 존재하고 숫자이며 탐색할 객체가 순수 배열입니다
이 조건을 충족한 후 isArray의 결과에 따라 개별적으로 순회를 시작합니다. "배열"의 경우 for 루프를 사용하고 객체의 경우 for...in 루프를 사용합니다
// Go through the array, translating each of the items to their if ( isArray ) { for ( ; i < length; i++ ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret[ ret.length ] = value; } }
// Flatten any nested arrays return ret.concat.apply( [], ret );마지막으로 결과 집합이 평면화됩니다. 이 단계가 필요한 이유는 무엇입니까? map은 배열을 확장할 수 있기 때문에 이전 세 번째 예의 경우입니다.
$.map( [0,1,2], function(n){ return [ n, n + 1 ]; });이렇게 사용하면 새로 얻어지는 배열은 2차원 배열이므로 차원을 줄여야 합니다
ret.concat.apply([], ret)는 [].concat.apply([], ret)와 동일합니다. Apply의 두 번째 매개변수가 ret 배열을 여러 매개변수로 나누기 때문입니다. 2차원 배열을 1차원 배열로 변환하기 위해 concat에 전달하는 것은 수집할 가치가 있습니다
맵 방식에 대한 간단한 분석이 완료되었습니다. 역량의 한계로 인해 틀린 부분이 있으면 정정해 주시기 바랍니다.
위 내용은 이 글의 전체 내용입니다. 모두 마음에 드셨으면 좋겠습니다.