jquery的serializeArray、param 與serializeArray 的區別與源碼解析


jQuery.param( obj, traditional )

為url查詢或者ajax 將對象或者數組轉為url參數或ajax參數,是掛在jQuery對象上的靜態方法,有碼有真相:

var myInfo = {
        userid:'123',
        fullname:['henry','li'],
        intro:{html:5, css:3}            
    };
    console.log($.param(myInfo));
    //"userid=123&fullname%5B%5D=henry&fullname%5B%5D=li&intro%5Bhtml%5D=5&intro%5Bcss%5D=3"
    //userid=123&fullname[]=henry&fullname[]=li&intro[html]=5&intro[css]=3"
    console.log($.param(myInfo),true);
    //"a=%5Bobject+Object%5D&b=1&b=2&b=3"
    //"a=[object+Object]&b=1&b=2&b=3"

可以看出第二個參數類似於控制深度。

源碼

// Serialize an array of form elements or a set of
// key/values into a query string
jQuery.param = function( a, traditional ) {
    var prefix,// 循環的鍵命名 for(var k in)  這里即k
        s = [],//返回的數據
        add = function( key, value ) {
            //key value對應循環中每項的name和值如:<input name="" value=""、{key:value}
            // 如果value是function,那么計算出返回值
            value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
            //轉為key1=value&key2=value2的形式
            s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
        };

    // Set traditional to true for jQuery <= 1.3.2 behavior.
    // 設置第二個參數,如果第二個參數等於undefined,取jQuery.ajaxSettings.traditional
    if ( traditional === undefined ) {
        traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
    }

    // If an array was passed in, assume that it is an array of form elements.
    // 第一個參數為數組或者表單的elements
    // 為數組或者jquery表單對象,不存在第二個參數的問題(a[]=1;a[]=2)
    if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
        // Serialize the form elements
        // 循環取name與value
        jQuery.each( a, function() {
            add( this.name, this.value );
        });

    } else {
        // If traditional, encode the "old" way (the way 1.3.2 or older
        // did it), otherwise encode params recursively.
        // 為對象的時候,需要照顧第二個參數,即深度
        for ( prefix in a ) {
            //調用另外一個方法,傳入key,obj[k],深度,add回調方法
            buildParams( prefix, a[ prefix ], traditional, add );
        }
    }

    // Return the resulting serialization
    return s.join( "&" ).replace( r20, "+" );
};

var r20 = /%20/g,
    rbracket = /\[\]$/,
    rCRLF = /\r?\n/g,
    rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
    rsubmittable = /^(?:input|select|textarea|keygen)/i;
    
function buildParams( prefix, obj, traditional, add ) {
    var name;

    if ( jQuery.isArray( obj ) ) {
        // Serialize array item.
        // 數組分支
        jQuery.each( obj, function( i, v ) {
            // 如果第二個參數為真,則直接調用自身會生成類似 a=object  這樣的數組
            // 或者參數為“數組”  key[0]或者key[name]
            if ( traditional || rbracket.test( prefix ) ) {
                // Treat each array item as a scalar.
                // 處理
                add( prefix, v );

            } else {
                // Item is non-scalar (array or object), encode its numeric index.
                //反之參數key設置為 key[i] 循環調用自身,這時候循環中的自身會進入下一步
                buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
            }
        });

    } else if ( !traditional && jQuery.type( obj ) === "object" ) {
        //如果參數不為真,調用自身,進入第一步
        // Serialize object item.
        for ( name in obj ) {
            buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
        }

    } else {
        // Serialize scalar item.
        // 每項的操作
        add( prefix, obj );
    }
}

.serializeArray()

這個是掛載在jQuery.fn方法上的,將當前jQuery form對象轉為數組對象,實例

 

var r20 = /%20/g,
    rbracket = /\[\]$/,
    rCRLF = /\r?\n/g,
    rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
    rsubmittable = /^(?:input|select|textarea|keygen)/i;
serializeArray: function() {
        //jQuery.fn.map
        return this.map(function() {
            // Can add propHook for "elements" to filter or add form elements
            // 如果當前對象具有elements的prop,則使用,反之使用自身
            // elements是原生js中表單所有的input。 如:document.forms[0].elements
            var elements = jQuery.prop( this, "elements" );
            return elements ? jQuery.makeArray( elements ) : this;
        })
        .filter(function() {//jQuery.fn.filter
            var type = this.type;
            // Use .is(":disabled") so that fieldset[disabled] works
            // 過濾掉沒有name、disabled的、可以提交的幾個標簽,如過是可選中的元素,則checked為真
            return this.name && !jQuery( this ).is( ":disabled" ) &&
                rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
                ( this.checked || !rcheckableType.test( type ) );
        })
        .map(function( i, elem ) {////jQuery.fn.map
            var val = jQuery( this ).val();
            //設置value
            return val == null ?
                null :
                jQuery.isArray( val ) ?
                    jQuery.map( val, function( val ) {
                        return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
                    }) :
                    { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
        }).get();//轉為真正的數組
    }

其中使用的get方法就很簡單了

get: function( num ) {
        return num != null ? 

            // Return a 'clean' array
            ( num < 0 ? this[ num + this.length ] : this[ num ] ) : 

            // Return just the object
            slice.call( this );
    }
//我們也可以使用自己的get方法。如: 
// Array.prototype.slice.call($('div'),0,1)//取到第一個div dom元素,相當於$('div').get(0)
// Array.prototype.slice.call($('div'))//取到所有,相當於$('div').get()


至於jQuery.prop方法,需要新起一篇文章介紹了。簡單的說,就是獲取元素的prop。  element.checked、element.value,是從attr中分離出來的

.serialize

serialize就簡單了,相當於serializeArray + parmp,將表單直接轉為url查詢字符串。代碼也簡單。同樣是在jQuery的fn上

 

serialize: function() {
        return jQuery.param( this.serializeArray() );
},


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM