(92-176)

26074 단어
원형 정의
jQuery.fn = jQuery.prototype = {

    // The current version of jQuery being used

    jquery: version,



    constructor: jQuery,



    // Start with an empty selector

    selector: "",



    // The default length of a jQuery object is 0

    length: 0,



    toArray: function() {

        return slice.call( this );

    },



    // Get the Nth element in the matched element set OR

    // Get the whole matched element set as a clean array

    get: function( num ) {

        return num != null ?



            // Return just the one element from the set

            ( num < 0 ? this[ num + this.length ] : this[ num ] ) :



            // Return all the elements in a clean array

            slice.call( this );

    },



    // Take an array of elements and push it onto the stack

    // (returning the new matched element set)

    pushStack: function( elems ) {



        // Build a new jQuery matched element set

        var ret = jQuery.merge( this.constructor(), elems );



        // Add the old object onto the stack (as a reference)

        ret.prevObject = this;

        ret.context = this.context;



        // Return the newly-formed element set

        return ret;

    },



    // Execute a callback for every element in the matched set.

    // (You can seed the arguments with an array of args, but this is

    // only used internally.)

    each: function( callback, args ) {

        return jQuery.each( this, callback, args );

    },



    map: function( callback ) {

        return this.pushStack( jQuery.map(this, function( elem, i ) {

            return callback.call( elem, i, elem );

        }));

    },



    slice: function() {

        return this.pushStack( slice.apply( this, arguments ) );

    },



    first: function() {

        return this.eq( 0 );

    },



    last: function() {

        return this.eq( -1 );

    },



    eq: function( i ) {

        var len = this.length,

            j = +i + ( i < 0 ? len : 0 );

        return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );

    },



    end: function() {

        return this.prevObject || this.constructor(null);

    },



    // For internal use only.

    // Behaves like an Array's method, not like a jQuery method.

    push: push,

    sort: arr.sort,

    splice: arr.splice

};

1. jquery: version 버전 정보,constructor: jQuery 원형의 구조 함수 속성을 함수 jQuery,selector: ", 속성 저장 선택기,length 저장 jQuery 대상의 길이로 수정하고 jQuery 대상을 그룹 대상으로 모방하여 처리 그룹처럼 jQuery 대상을 처리할 수 있도록 합니다.
2. 클래스 그룹을 그룹으로 전환
//          

var a = { 0: 2, 1: 4, 2: 6,length:3}

console.log(Array.prototype.slice.call(a));//[ 2, 4, 6 ]

jQuery 대상은 클래스 그룹 대상입니다. 슬라이스로 그룹으로 전환할 수 있습니다.
3.get 방법
var arr = [],

slice = arr.slice;

//   get,            get    

jQuery.fn.get =  function( num ) {

        return num != null ?



            // Return just the one element from the set

            ( num < 0 ? this[ num + this.length ] : this[ num ] ) :



            // Return all the elements in a clean array

            slice.call( this );

}

var $div = $('div')

//   0

//      []       

console.log($div.get(0) === $div[0])



//    

console.log($div.get(-1))



//

console.log($div.get())

여기 세 개의 연산자 [con]을 먼저 말씀드릴까요?[code] :[code];세 개의 예산부호는 If() {}else() {}와 같다.
if( a != null ){

    if( a<0 ){

        this[ num + this.length ]

    }else{

        this[ num ] 

    }

}else{

    slice.call( this )

}



//   

a != null ?( num < 0 ? this[ num + this.length ] : this[ num ] ) :slice.call( this );

비교해 보면 기능과 마찬가지로 코드의 양이 줄어들고 가독성이 떨어진다.자기 취사선택.
음수 상황에서 length+index = 원소의 위치.
4.jQuery 객체 스택.
var $ = {0:1,prev: Object.prototype}

console.log($[0])

$ = {0:2,prev:$}

console.log($[0])

$ = {0:3,prev:$}

console.log($[0])



//  

$ = $.prev

console.log($[0])

이 예에서 우리는 새로운 대상에 이전 대상에 대한 인용을 저장함으로써 창고식의 역추적 접근을 실현할 수 있다.
jQuery 대상은 스트리밍 기능에서 이 원리를 운용했다. 스트리밍 작업 후에 되돌아오는 것은 새로운 jQuery 대상이다. 이 새로운 대상은 이전 대상에 대한 인용이 존재하여 체인식의 역추적 접근을 실현한다.
다음은 jQuery의 실현을 살펴보겠습니다.
var slice = [].slice;

jQuery.fn.pushStack = function( elems ) {

    // Build a new jQuery matched element set

    var ret = jQuery.merge( this.constructor(), elems );



    // Add the old object onto the stack (as a reference)

    ret.prevObject = this;

    ret.context = this.context;



    // Return the newly-formed element set

    return ret;

}

jQuery.fn.slice = function() {

        return this.pushStack( slice.apply( this, arguments ) );

}

jQuery.merge = function( first, second ) {

        var len = +second.length,

            j = 0,

            i = first.length;



        for ( ; j < len; j++ ) {

            first[ i++ ] = second[ j ];

        }



        first.length = i;



        return first;

}

jQuery.fn.end = function() {

        return this.prevObject || this.constructor(null);

}

console.log($('li').slice(2,4).css('background-color','red').end());

여기pushStack이 맡은 역할은 이전 대상에 대한 인용 속성을 설정하는 것입니다. 초기화된 jQuery 대상이 아니기 때문에 상하문context를 설정해야 합니다.merge의 역할은 합병 대상이length를 설정하는 것입니다.
end의 역할은 이전 대상을 되돌려줍니다. 이 속성이 없으면 빈 jQuery 대상을 구성합니다. (because constructor: jQuery,line 96)
어쨌든, 스트리밍은 현재 존재하는 jQuery 대상을 선별하기 위해서입니다. 창고를 사용하는 이유는 우리가 체인 호출에서 거슬러 올라갈 수 있기 때문입니다. 이것은 jQuery 대상을 재구성하는 것보다 훨씬 빠릅니다.
5. 코드에서 jQuery를 똑똑히 볼 수 있다.fn.each는 실제로 jQuery입니다.each 방법의 첫 번째 매개 변수는this에 전달된다. 이 방법은 일찍부터 빈번하게 사용되기 때문에 여기서 먼저 분석한다.
//simple

function isArraylike(obj){

    return obj.length - 1 in obj;

}

// args is for internal usage only

jQuery.each = function( obj, callback, args ) {

        var value,

            i = 0,

            length = obj.length,

            isArray = isArraylike( obj );



        if ( args ) {

            if ( isArray ) {

                for ( ; i < length; i++ ) {

                    value = callback.apply( obj[ i ], args );



                    if ( value === false ) {

                        break;

                    }

                }

            } else {

                for ( i in obj ) {

                    value = callback.apply( obj[ i ], args );



                    if ( value === false ) {

                        break;

                    }

                }

            }



        // A special, fast, case for the most common use of each

        } else {

            if ( isArray ) {

                for ( ; i < length; i++ ) {

                    value = callback.call( obj[ i ], i, obj[ i ] );



                    if ( value === false ) {

                        break;

                    }

                }

            } else {

                for ( i in obj ) {

                    value = callback.call( obj[ i ], i, obj[ i ] );



                    if ( value === false ) {

                        break;

                    }

                }

            }

        }



        return obj;

};



var a1 = [1,2,3],

  a2 = {0:1,1:2,2:3,length:3},

  a3 = {a:1,b:2,c:3};

jQuery.each(a1,function(i,el){

    console.log(i+':'+el)

})

jQuery.each(a2,function(i,el){

    console.log(i+':'+el)

})

jQuery.each(a3,function(i,el){

    console.log(i+':'+el)

})

상황 분석:
~ 매개변수 상황
~수 그룹 및 클래스 그룹 상황
대상 상황
~false로 되돌아오면 반복 종료
효율성 분석:
~for in의 효율은 for(var i=0;i~forEach가 적용되지 않습니까?
이곳의 isArray는 실제적으로 수조와 클래스 수조를 가리킨다.큰 if...else는 코드를 두 모듈로 나눈다. 코드는 기본적으로 같고 저자는 파라미터가 있는 내부에서만 사용된다고 주석을 달았다.먼저 파라미터가 없는 상황을 토론합시다.
분기를 하고, 그룹 클래스의 그룹을 분류할 때, for로 순환하고,callback.콜(obj[i], i,obj[i])은 콜 방법을 이용하여this를 현재 대상으로 지정하고 리셋 함수를 호출한다. 뒤에 있는 매개 변수는 i 위치,objec[i] 현재 대상이다.false가 스트리밍을 중지하기 때문에 판단을 한 다음break;.대상의 경우, 순환할 때 for in을 사용합니다.
처음에 파라미터를 포함했을 때와 파라미터가 없는 상황은 기본적으로 같지만 관건적인 부분은callback이다.apply(obj[i],args) 리셋 함수 호출의 매개 변수는 완전히 다르다. 여기에 사용하는 것은 apply 방법이다.
6.map과 each는 비슷하지만 맵의 측면 중점은 반환값 처리이고 each는 모든 대상에 하나의 함수를 집행하는 것이다.
//           ,           ,      。

var arr = [];

concat = arr.concat;



function isArraylike( obj ) {

    var length = obj.length,

        type = jQuery.type( obj );



    if ( type === "function" || jQuery.isWindow( obj ) ) {

        return false;

    }



    if ( obj.nodeType === 1 && length ) {

        return true;

    }



    return type === "array" || length === 0 ||

        typeof length === "number" && length > 0 && ( length - 1 ) in obj;

}

jQuery.fn.map = function( callback ) {

        return this.pushStack( jQuery.map(this, function( elem, i ) {

            return callback.call( elem, i, elem );

        }));

};

// arg is for internal usage only

jQuery.map =  function( elems, callback, arg ) {

        var value,

            i = 0,

            length = elems.length,

            isArray = isArraylike( elems ),

            ret = [];



        // Go through the array, translating each of the items to their new values

        if ( isArray ) {

            for ( ; i < length; i++ ) {

                value = callback( elems[ i ], i, arg );



                if ( value != null ) {

                    ret.push( value );

                }

            }



        // Go through every key on the object,

        } else {

            for ( i in elems ) {

                value = callback( elems[ i ], i, arg );



                if ( value != null ) {

                    ret.push( value );

                }

            }

        }



        // Flatten any nested arrays

        return concat.apply( [], ret );

};

console.log($(':checkbox').map(function() {

    return this.id;

}).get().join())

상황 분석:
~수 그룹 및 클래스 그룹 상황
대상 상황
~value 없음
효율성 분석:
~for in의 효율은 for(var i=0;i상황은 each와 기본적으로 같습니다.if(value!=null) 판단값이 존재하지 않는 경우,this.pushStack이 창고에 가입합니다.
apply의 두 번째 매개 변수는 수조이기 때문에 이전에 수집한 데이터 수조(데이터 수집이 편리)를 데이터 처리로 활용할 수 있다.
var arr = [];

concat = arr.concat;

var ret = [[1,2],[3,4],5];

console.log([].concat(1,[2,3]))

console.log([].concat(ret)) //      

console.log(concat.apply([],ret)) //  

 7.slice는 이전에 말한 적이 있는데, 다음은 주로 eq를 말한다
eq와 get 방법은 비슷하다. 두 가지 차이가 있다. 하나는 매개 변수를 전송하지 않을 때와 넘쳐나는 처리 방식이고, 하나는 eq의 결과가pushStack 처리를 할 것이다.
jQuery.fn.eq = function( i ) {

        var len = this.length,

            j = +i + ( i < 0 ? len : 0 );

        return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );

}

console.log($('div').eq(0))

두 가지 방법의 판단 부분이 비슷하기 때문에 매개 변수와 넘침을 고려하지 않으면 안 된다.get 방법을 직접 호출할 수 있습니다.
jQuery.fn.eq = function(i){

    return this.pushStack([this.get(i)])

}

console.log($('div').eq(1))

 
마지막으로 저자는push,sort,splice 수조를 저장합니다.

좋은 웹페이지 즐겨찾기