jquery 源码分析 jQuery类 定义

本文深入解析了jQuery的核心函数实现原理,包括如何处理不同类型的输入参数、修正HTML标签、执行额外函数以及使用关键辅助函数如clean、get和each等。通过具体示例说明了jQuery在DOM操作中的灵活性和强大功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// Global undefined variable
window.undefined = window.undefined;
function jQuery(a,c) {

	// Shortcut for document ready (because $(document).each() is silly)
	/*
		举例: jQuery(function(){alert('All Tags Finished');}
	 */
	if ( a && a.constructor == Function && jQuery.fn.ready )
		return jQuery(document).ready(a);

	// Make sure that a selection was provided
	a = a || jQuery.context || document;

	// Watch for when a jQuery object is passed as the selector
	/*jquery: "$Rev: 509 ";,判断是否为jQuery的包装集可以利用该参数,该参数在后来返回其版本号 */
	if ( a.jquery )
		return $( jQuery.merge( a, [] ) ); /*jQuery.merge合并两个数组,不重复相同元素*/

	// Watch for when a jQuery object is passed at the context
	if ( c && c.jquery )
		return $( c ).find(a);
	
	// If the context is global, return a new object
	/*第一次以函数的身份执行,第二次以类的名义操作*/
	if ( window == this )
		return new jQuery(a,c);

	// Handle HTML strings
	/*遇到html标签,比如<div>
	* clean函数,见425行
	* */
	var m = /^[^<]*(<.+>)[^>]*$/.exec(a);
	if ( m ) a = jQuery.clean( [ m[1] ] );

	// Watch for when an array is passed in
	this.get( a.constructor == Array || a.length && !a.nodeType && a[0] != undefined && a[0].nodeType ?
		// Assume that it is an array of DOM Elements
		jQuery.merge( a, [] ) :

		// Find the matching elements and save them for later
		/*选择符一般从这儿开始正式步入查找阶段*/
		jQuery.find( a, c ) );

  // See if an extra function was provided
  /*有额外参数为函数的情况*/
	var fn = arguments[ arguments.length - 1 ];
	
	// If so, execute it in context
	if ( fn && fn.constructor == Function )
		this.each(fn);
}

jQuery定义为类,上面这个类考虑到的参数是各种形式(函数,包装集,字符串等),如果遇到不符合条件的tag,首选调用clean函数来修复这个tag,clean函数代码如下:

/*修正html标签,功能包括关闭标签、自动转小写、自动删除不被识别的标签、格式化缩进等*/
	/*后面的?*/
	clean: function(a) {
		var r = [];
		for ( var i = 0; i < a.length; i++ ) {
			if ( a[i].constructor == String ) {

				// 如果是表格元素,修正该元素
				var table = "";
				/*如果存在thead或者tbody在第一位*/
				if ( !a[i].indexOf("<thead") || !a[i].indexOf("<tbody") ) {
					table = "thead";
					a[i] = "<table>" + a[i] + "</table>";
				} 
				/*如果存在tr并且在第一位,注意-1为true*/
				else if ( !a[i].indexOf("<tr") ) {
					table = "tr";
					a[i] = "<table>" + a[i] + "</table>";
				}
				/*如果存在th,在第一位*/
				 else if ( !a[i].indexOf("<td") || !a[i].indexOf("<th") ) {
					table = "td";
					a[i] = "<table><tbody><tr>" + a[i] + "</tr></tbody></table>";
				}
	
				var div = document.createElement("div");
				div.innerHTML = a[i]; /*这里就是修正的目的*/
				/*如果是table等表格元素*/
				if ( table ) {
					div = div.firstChild;
					if ( table != "thead" ) div = div.firstChild;
					if ( table == "td" ) div = div.firstChild;
				}
				//将修正后的元素添加
				for ( var j = 0; j < div.childNodes.length; j++ )
					r.push( div.childNodes[j] );
				} else if ( a[i].jquery || a[i].length && !a[i].nodeType )
					for ( var k = 0; k < a[i].length; k++ )
						r.push( a[i][k] );
				else if ( a[i] !== null )
					r.push(	a[i].nodeType ? a[i] : document.createTextNode(a[i].toString()) );
		}
		return r;
	},
这里clean函数还不是太懂。

get函数返回包装集的参数位置对应的值,当参数为空时,返回所有值

get: function( num ) {
		// Watch for when an array (of elements) is passed in
		if ( num && num.constructor == Array ) {

			// Use a tricky hack to make the jQuery object
			// look and feel like an array
			this.length = 0;
			/*将两个数组拼接,为什么要返回这样的数组?*/
			[].push.apply( this, num );
			
			return this;
		} else
			return num == undefined ?

				// Return a 'clean' array
				jQuery.map( this, function(a){ return a } ) :

				// Return just the object
				this[num];
	},

还有所使用的each函数:
	/*apply函数置换调用者的this变量*/
	each: function( obj, fn, args ) {
		if ( obj.length == undefined )
			for ( var i in obj )
				fn.apply( obj[i], args || [i, obj[i]] );/*args为fn的参数*/
		else
			for ( var i = 0; i < obj.length; i++ )
				fn.apply( obj[i], args || [i, obj[i]] );
		return obj;
	},
这里转一下apply的调用:

比较下面两端代码

var obj={s:'obj'};
window.s="win";
function cat(a){
    alert(this.s+a);
}
cat.apply(obj,'obj');
cat.apply(null,'obj');

apply的作用是修改函数(类)中的this的取值,在jquery源码中,这经常用到。因为this的取值可以修改这意义重大。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值