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方法得到结果!
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用+替换掉!这也是为什么在浏览器中输入中文空格全部变成加号的原因!