jQuery源码分析之jQuery.param方法详解

buildParams方法源码:

var rbracket = /\[\]$/;
function buildParams1( prefix, obj, traditional, add ) {
	var name;
     //传入的是一个对象,这里是false
	if ( jQuery.isArray( obj ) ) {
		// Serialize array item.
		//传入的第二个students是数组,那么会对这个数组再次进行遍历
		//如果traditional为true,或者这是数组是空的,那么调用add方法传入键名和这个数组项!
		jQuery.each( obj, function( i, v ) {
			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.
				//传入参数形式为:buildParams1("students['']","a1",traditional,add)
				//也就是这时候在add方法里面的key就是students[]这种形式的!也就是说这时候的key就是stutents[]!
				//然后对这个key进行编码!
			buildParams1( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
			}
		});
    //如果没有传入traditional同时还是对象
	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
		// Serialize object item.
		//那么就会再次进行深度遍历,然后遍历出所有的属性,所以这里是深度遍历的!
		for ( name in obj ) {
			buildParams1( prefix + "[" + name + "]", obj[ name ], traditional, add );
		}
	} else {
		// Serialize scalar item.
		add( prefix, obj );
	}
}
params源码:

//%20是空格符号
var r20 = /%20/g;
jQuery.param1 = function( a, traditional ) {
	var prefix,
		s = [],
		add = function( key, value ) {
			//如果value是函数,那么调用函数得到返回值作为真正的value值,如果value是null或者undefined
			//那么直接value是空字符串,其它情况value不变!
			// If value is a function, invoke it and return its value
			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
			//把key和value值都进行了转码调用encodeURIComponent
			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
		};
	// Set traditional to true for jQuery <= 1.3.2 behavior.
	if ( traditional === undefined ) {
		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
	}
	// If an array was passed in, assume that it is an array of form elements.
	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
		// Serialize the form elements
		jQuery.each( a, function() {
			//这里面的each指向前面的数组中的内容,也就是是一个对象!
			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 ) {
			//第二种方式jQuery.param1({ name:"CodePlayer", age:18 });调用
			//那么传入的第一个参数是键名,第二个参数是键值,第三个是traditional,第四个是add方法
			buildParams1( prefix, a[ prefix ], traditional, add );
		}
	}
	// Return the resulting serialization
	//最后把数组s中的所有的查询字符串通过&链接起来,并且把%20也就是空格用+表示!
	return s.join( "&" ).replace( r20, "+" );
};
测试代码1:

var obj = [
       { name: "names", value: { first:"Jim", second:"W", last:"Green" } },
       { name: "uid", value: [ { name: "a", value: 1}, "James" ] }
];
var result=jQuery.param1(obj,false);
alert(result);
note:这时候传入的是数组,那么在param方法里面直接调用通过each方法迭代处理每一个对象,在add里面进行处理!对键值和键名都调用encodeURIComponent方法得到结果!
测试代码2:

var result1=jQuery.param1({ name:"CodePlayer", age:18 ,students:["a1","a2"]});
alert(result1);
note:这次传入的参数不是数组对象,所以调用for..in循环,对于最后一次调用buildParams传入的是一个数组,然后在 buildParams里面继续对这个数组迭代,最后还是调用add方法放入数组s中!这时候传入的键值就是"students[]"等这种类型,所以他的键名最终会加上数组的标记!至于键值还是"a1"等数组!

总结:

(1)因为这个方法用于ajax请求参数的设定,所以要对键名和键值进行编码,调用了encodeURIComponent!如果是数组或者对象那么键名可能要加上[],

(2)最后把数组成员通过&符号链接起来,并且把空格,也就是%20用+替换掉!这也是为什么在浏览器中输入中文空格全部变成加号的原因!

你可能感兴趣的:(jQuery源码分析之jQuery.param方法详解)