视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
jQuery之.grep()函数的四个疑问分析
2020-11-27 20:16:04 责编:小采
文档


问题1:jQuery.grep源码是什么?

//grep函数,第三个参数表示是否根据fn的结果取反!
grep: function( elems, callback, invert ) {
var callbackInverse,
matches = [],
i = 0,
//保存数组个数
length = elems.length,
//对传入的第二个参数取反,true变成false,false变成true
//如果invert为false,即!inverse为true,那么直接把函数返回true的元素加入,所以期望callbackExpect的就是true
callbackExpect = !invert;
// Go through the array, only saving the items
// that pass the validator function
for ( ; i < length; i++ ) {
//如果invert是false,表示不取反,那么如果fn返回true,就直接加入进去matches数组
//获取回调函数结果的返回值的取反的结果
callbackInverse = !callback( elems[ i ], i );
if ( callbackInverse !== callbackExpect ) {
matches.push( elems[ i ] );
}
}
return matches;
}

问题2:jQuery.grep调用方式有那些?

在winnow函数中

 if ( qualifier.nodeType ) {
	return jQuery.grep( elements, function( elem ) {//没有第三个参数,表示获取执行函数后返回为true元素在结果数组中
	return ( elem === qualifier ) !== not;
	});

	}

在winnow函数中还有调用

return jQuery.grep( elements, function( elem ) {
	return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;<span style="font-family: Arial, Helvetica, sans-serif;">//没有第三个参数,表示获取执行函数后返回为true元素在结果数组中</span>
	});

还是在winnow方法中

	return jQuery.grep( elements, function( elem, i ) {
	/* jshint -W018 */
	return !!qualifier.call( elem, i, elem ) !== not;<span style="font-family: Arial, Helvetica, sans-serif;">//没有第三个参数,表示获取执行函数后返回为true元素在结果数组中</span>
	});

在jQuery.buildFragment中调用

 jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );

该方法用于将所有的input元素的defaultChecked属性设置为和checked一样

// Used in buildFragment, fixes the defaultChecked property
var rcheckableType = (/^(?:checkbox|radio)$/i);
function fixDefaultChecked( elem ) {
	if ( rcheckableType.test( elem.type ) ) {
	elem.defaultChecked = elem.checked;//这里没有明确返回真或者假,所以他只是用来修改元素,而不再保存修改后的数组!
	}
}

问题3:jQuery.grep方法的作用是什么?

如果没有传入第三个参数的情况下,表示我们希望返回调用回调函数后结果为true的元素,所以jQuery.grep的作用就在于筛选了,只有满足特定条件的元素才会出现在结果数组中!记住:该函数的返回值是数组哦!
我们通过下面例子来分析如何选择id和class都是father的元素

 <p class="father" id="father" style="background-color:red;height:400px;background-color:#ccc;"> 
</p> 
 <p class="father" style="background-color:red;height:400px;background-color:#ccc;"> 
</p>

JS部分

 //对每一个元素进行筛选,只有符合条件的元素才会在结果数组中!
 var result=jQuery.grep($(".father"),function(elem,index)
	 {
	 return elem.id==="father";
	 //grep通过false,true来判断是否在结果集合中;map通过明确的return elem
	 //而each通过false,true决定是否退出循环
	 });
 console.log(result);//打印[p#father.father]

所以grep是通过返回值的真假来决定返回的元素的,所有满足条件的元素构成一个DOM集合!
HTML部分不变,我们把JS部分修改为:

 //对每一个元素进行筛选,只有符合条件的元素才会在结果数组中!
 var result=jQuery.grep($(".father"),function(elem,index)
	 {
	 return elem.id==="father";
	 //grep通过false,true来判断是否在结果集合中;map通过明确的return elem
	 //而each通过false,true决定是否退出循环
	 },true);
 console.log(result);//[p.father]

这时候因为第三个参数是true,因为在内部会取反,所以表示我们希望值是false的元素出现在结果数组中,所以结果数组中只包含第二个p元素。

其实源码中的代码可以修改为:

//下面的代码可以修改为:
 callbackResult = callback( elems[ i ], i );//调用函数的结果
if ( callbackResult === callbackExpect ) {//如果调用的结果和期望的结果一样,那么直接放进结果数组返回
matches.push( elems[ i ] );
}

问题4:在jQuery.grep中上下文和参数是什么?

解答:因为没有明确调用call或者apply,所以上下文由运行环境决定。第一个参数是元素,第二个参数是下标(只有jQuery.each,和实例each,map方法第一个参数是下标,第二个参数是元素!)

总结:

(1)$.each方法强调的是遍历,也就是遍历出所有的元素然后执行一个回调函数,如果return false那么就停止后面的调用;grep强调的是按照一个函数对所有的元素进行筛选,让所有元素执行一个函数看看返回值是否满足期望的返回值,如果满足就可以在结果数组中,第三个参数表示是否取反,所以grep强调筛选;map强调的是修改,也就是对所有的元素集合进行修改.(map强调修改,grep强调筛选,each强调遍历)

(2)each的回调函数传入的参数是下标和元素,下标在前元素在后,其它grep或者map方法传入的参数是元素和下标,元素在前下标在后(实例map,each方法除外)!

下载本文
显示全文
专题