测试代码1:
function w( html ){ document.body.innerHTML += "<br/>" + html; } var obj = { 0:"CodePlayer", 1: "Hello", 2: 18, 3: true }; obj.length = 4; // 类数组对象不是真正的数组 w( obj instanceof Array ); // false var arr = $.makeArray( obj ); w( arr instanceof Array ); // true w( arr.join(" ") ); // CodePlayer Hello 18 true w( arr.length ); // 4测试代码2:
alert({}.toString.call( $.makeArray("xxx")));//返回[object Array] alert(jQuery.makeArray("xxx").length)//返回1 //如果第一个参数不是array,也不是类数组对象,那么直接当作数组返回 //数组里面只是放一个对象["xxx"]因为我们虽然给makeArray传入了字符串,但是该字符串具有length属性,所以他最后被放在结果数组中了!
测试代码3:
//其实merge函数不要求第二个参数是数组,可以是对象! //alert( $.makeArray("xxx",[1,2]));返回数组[1,2,xxx] //给两个例子: var obj={ 0:"xx", 1:"female", length:2 } var arr=[1,2,3]; alert($.merge(arr,obj));//打印1,2,3,xx,female也就是只会merge下标是数字的元素,length下标的没有合并。 //从$.merge的源码可以知道,源码如下:他是通过下标访问,不是通过for..in迭代的!所以合并的中没有打印length为2属性 //while ( j < len ) { //first[ i++ ] = second[ j++ ]; //}这是关于merge第二个参数传入对象的情况
//在给一个例子: var obj={0:"xxx",1:"yy",length:2}; var result=$.makeArray("sex",obj);//注意:"sex"通过Object方法转化成为字符串对象了,具有length属性,所以isArrayLike返回为true,这也能合并! //merge函数传入第二个参数是类数组对象! alert(result[0]+"->"+result[1]+"->"+result[2]+"->"+result[3]);//打印xxx,yy,sex,undefined所以没有合并下标是length的属性,只会合并下标是数组的属性!
我们可以给makeArray传入第二个参数,而且这是字符串是JSON格式,所以通过makeArray返回的就不是数组了,而是JSON对象!但是必须第二个参数含有length属性!
总结:(1)isArraylike(Object("Name"))将字符串转换成了字符串对象,该对象有length属性,因此下面的例子会把"Name"这个字符串对象封装到jQuery对象上面!
(4)第二个参数用于内部使用,如$.makeArray([document.getElementsByTagNames("div")],$());第二个参数可以是JSON,如$.makeArray(document.getElementsByTagName("div"),{length:0});。但是建议传入的JSON要有length具体参考merge方法
makeArray源码分析:
makeArray: function( arr, results ) { var ret = results || []; //如果传入了第一个参数 if ( arr != null ) { if ( isArraylike( Object(arr) ) ) {//转化为相应的封装类型,如果是字符串那么有length属性!$.makeArray("sex").length字符串长度为1! jQuery.merge( ret, typeof arr === "string" ? [ arr ] : arr ); } else { //如果不是数组或者类数组,直接把他push进去,例如 push.call( ret, arr ); } } return ret; }
注意:
(1)makeArray的第二个参数默认是一个数组,也就是把传入的第一个参数变成数组对象。但是在jQuery内部调用可以传入第二个参数,如jQuery对象,那么最后的返回值就是jQuery类型了,如下面代码:
var arr=[1,2,4]; var result=$.makeArray(arr,$()); console.log(result);//jQuery对象 console.log(result instanceof jQuery);//打印true第一个参数如果是DOM数组,表示把DOM数组上的所有的DOM对象封装到空的jQuery对象上:
var result=$.makeArray([$("#result")[0]],$()); //包含一个DOM对象的jQuery对象,第一个元素是一个DOM数组表示把这个DOM数组 //中的所有的DOM封装到后面的jQuery对象上面! console.log(result);第一个参数如果是一个String数组,那么也会把这个String对象作为一个整体封装到空的jQuery对象上:
var result=$.makeArray(["Name"],$()); //因为Object("Name")把字符串转化成为对象了,该对象有length属性,于是isArrayLike成为true,就直接把前面字符串对象作为整体封装到jQuery对象上! console.log(result);