• 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 = /
    ?
    /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 = /
    ?
    /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, "
    " ) };
                        }) :
                        { name: elem.name, value: val.replace( rCRLF, "
    " ) };
            }).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() );
    },
  • 相关阅读:
    操作系统概述
    18 文本处理
    17 正则表达式(重点)
    16 归档和备份
    15 查找文件
    博客园图片折叠
    EF6学习笔记十五:调试EF框架源码
    EF6学习笔记十四:上下文管理
    Sqlserver和LocalDB创建数据库时默认字符集不一样
    EF6学习笔记十三:基础知识完结,零碎问题补缺
  • 原文地址:https://www.cnblogs.com/henryli/p/3664291.html
Copyright © 2020-2023  润新知