rsingleTag.test('<div class="cl"></div>') //false
rsingleTag.test('<div></ddiv>') //false
这个正则表达式主要是对 html 的字符串进行验证,达到不出差错的效果。在这里不多介绍 exec 和正则表达式了。
下面来看下重点的处理 HTMl 字符串的情况:
if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) {
// 这个其实是强行构造了匹配 html 的情况的数组
match = [null, selector, null];} else {
match = rquickExpr.exec(selector);
}
// macth[1] 限定了 html,!context 对 #id 处理
if (match && (match[1] || !context)) {
// HANDLE: $(html) -> $(array)
if (match[1]) {
//排除 context 是 jQuery 对象情况
context = context instanceof jQuery ? context[0] : context;
// jQuery.merge 是专门针对 jQuery 合并数组的方法
// jQuery.parseHTML 是针对 html 字符串转换成 DOM 对象
jQuery.merge(this, jQuery.parseHTML(
match[1], context && context.nodeType ? context.ownerDocument || context : document, true));
// HANDLE: $(html, props)
if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
for (match in context) {
// 此时的 match 非彼时的 match
if (jQuery.isFunction(this[match])) {
this[match](context[match]);
// ...and otherwise set as attributes
} else {
this.attr(match, context[match]);
}
}
}
return this;
// 处理 match(1) 为 underfined 但 !context 的情况
} else {
elem = document.getElementById(match[2]);
if (elem) {
// this[0] 返回一个标准的 jQuery 对象
this[0] = elem;
this.length = 1;
}
return this;
}
// 处理一般的情况,find 实际上上 Sizzle,jQuery 已经将其包括进来,下章详细介绍
// jQuery.find() 为 jQuery 的选择器,性能良好
} else if (!context || context.jquery) {
return (context || root).find(selector);
// 处理 !context 情况
} else {
// 这里 constructor 其实是 指向 jQuery 的
return this.constructor(context).find(selector);
}
关于 nodeType,这是 DOM 的一个属性,详情 Node.nodeType MDN。nodeType 的值一般是一个数字,比如 1 表示 DOM,3 表示文字等,也可以用这个值是否存在来判断 DOM 元素,比如 context.nodeType。
整个 init 函数等构造逻辑,非常清晰,比如 (selector, context, root) 三个参数,分别表示选择的内容,可能存在的的限制对象或 Object,而 root 则默认的
jQuery(document) 。依旧采用 jQuery 常用的方式,对每一个变量的处理都非常的谨慎。如果仔细看上面两部分源代码,我自己也加了注释,应该可以把整个过程给弄懂。










