jQuery构造函数init参数分析(一)
在我的上一篇随笔里面分析了jQuery的构造函数,jQuery对象中有一个原型方法init才是是真正的构造函数,通过init的原型对象跟jQuery的原型对象保持引用关系使得init的实例可以正常调用jQuery的原型方法,就好像是jQuery的实例一样。下面就来看看init这个幕后的构造函数是怎么写的:
init: function( selector, context, rootjQuery ) { ... }
可以看到这个方法接受3个参数,其前两个参数是jQuery方法传递过来的
var jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' return new jQuery.fn.init( selector, context, rootjQuery ); },
Selector原则上可以输入任意值,但并不是所有值都是有意义的,只有undefined、DOM 元素、字符串、函数、jQuery 对象、普通 JavaScript 对象这几种类型是有效的,这个参数是通常是填写的但是不填写也不会报错
console.log($()); //[constructor: function, init: function, selector: "", jquery: "1.7.1", size: function…]
Context作为执行上下文或者叫执行范围可以不传入,或者传入 DOM 元素、jQuery 对象、普通 JavaScript 对象之一
参数 rootjQuery:包含了 document 对象的 jQuery 对象,用于 document.getElementById() 查找失败、selector 是选择器表达式且未指定 context、selector 是函数的情况,其实就是$(document)。
下面根据参数的不同分为12种情况逐个讨论
1.selector 可以转换为false
// Handle $(""), $(null), or $(undefined) if ( !selector ) { return this; }
源码中的注释已经写得很清楚了,当是这三种情况时直接return不进行任何处理
2.参数 selector 是 DOM 元素
例如: $(document)这种写法
// Handle $(DOMElement) if ( selector.nodeType ) { this.context = this[0] = selector; this.length = 1; return this; }
只要是dom元素肯定有节点类型,然后把这个节点变成jquery对象的第一个元素并且赋值给上下文context,length属性是jQuery的原型属性默认为0
// The default length of a jQuery object is 0 length: 0,
这里有了一个元素之后就把length属性修改为1。return this 操作使得函数执行后的结果依然是jQuery对象这样就可以实现类似$(document).each()这样的链式调用了。最终得到的类似这样的{0:document,context:document,length:1....}对象,其实所有的情况最后都会变成这种形式的对象,除了jQuery原型属性和方法之外就是获取的dom节点并且按照阿拉伯数字依次排列,所以我们可以使用$(selector)[0]的形式代替$(selector).get(0)来获取dom对象。例如:
<!doctype html> <html> <head> <title></title> </head> <body> <div></div> <div></div> <div></div> </body> <script src='jquery-1.7.1.js'></script> <script> console.log($('div')); /*[div, div, div, prevObject: jQuery.fn.jQuery.init[1], context: document, selector: "div", constructor: function, init: function…] 0: div
1: div
2: div
context: document
length: 3
prevObject: jQuery.fn.jQuery.init[1]__proto__: jQuery[0]
selector: "div"
.
*/
</script> </html>
3.参数是特殊的字符串“body”
由于body元素在一个文档对象中只有一个所以单独列出来处理
// The body element only exists once, optimize finding it if ( selector === "body" && !context && document.body ) { this.context = document; this[0] = document.body; this.selector = selector; this.length = 1; return this; }
这里有3个条件必须同时满足,第二个必须没有上下文的条件我也不是太理解,$(‘body’,document)这样的看起来很正常的写法也会被这种情况“忽视”
console.log($('body',document)); /* jQuery.fn.jQuery.init[1] 0: body context: document length: 1 prevObject: jQuery.fn.jQuery.init[1] selector: "body" __proto__: jQuery[0] */
虽然和$('body')的结果是一样的,但是却被当做两种情况来看待,可能是因为body只有一个上下文只能是document没有必要添加吧,否则又要判断上下文是不是document。第三个条件是保证document.body必须存在,那么什么情况下会前两个情况满足document.body又不存在呢?首先就是js代码先于html代码加载时会出现这个是初学者经常会犯的错误,通常我们要写成:
$(function(){...})
或者
$(document).ready(function(){...})
其实这两个是一样的调取的是一个方法,dom加载这一块以后在分析。对此我们可以做个测试html代码如下:
<!doctype html> <html> <head> <title></title> <script src='jquery-1.7.1.js'></script> <script> $('body') </script> </head> <body> <div></div> <div></div> <div></div> </body> </html>
然后再jQuery源代码里面输出selector、context和document.body
console.log(selector+context+document.body); // The body element only exists once, optimize finding it if ( selector === "body" && !context && document.body ) { this.context = document; this[0] = document.body; this.selector = selector; this.length = 1; return this; }
虽然我们只写了一个其实执行了四次,只有最后一次才是是我们调用后的结果,最后一次的结果是bodyundefinednull这个时候前两个就是满足的但是最后一个是null。回想起第一篇jQuery总体架构架构里面undefined会被重新,那么document.body会不会被重写为null呢?当我尝试在代码中修改时就会报错看来是不会的,那这个条件就是预防没有加载html就执行的情况吧
第四种是除了上述的字符串情况之外的其他字符串,情况比较多放在下一篇吧。
jQuery构造函数init参数分析(一)的更多相关文章
- jQuery构造函数init参数分析(三)
分析完了字符串情况剩下的就不多了. 5.参数selector是函数 这个就是很容易想到了,首先说一下dom加载.我们通常在head里面写脚本的时候需要等待文档加载在进行处理,js是这么写的 windo ...
- jQuery构造函数init参数分析(二)
接着上一篇随笔讨论. 如果selector是其他字符串情况就比较多了比较复杂了 // Handle HTML strings if ( typeof selector === "string ...
- 浅谈jQuery构造函数
$()函数到底做的什么 jQuery在前端领域路人皆知,对于一向喜欢玩js的博主来说,虽然能力有限,但是还是很喜欢研究他的做为.那么一个简单的美元符号$与一对常见的()括号,jQuery底层到底做了哪 ...
- jQuery学习笔记之jQuery.fn.init()的参数分析
这篇文章主要介绍了jQuery.fn.init()的参数分析,需要的朋友可以参考下 从return new jQuery.fn.init( selector, context, rootjQuer ...
- jQuery分析(3) - jQuery.fn.init
1.前言 上一篇jQuery分析(2)中了解了jQuery库的骨架实现原理,这就好比摇滚音乐,摇滚音乐不是某种音乐他就像一个音乐盒子,里面包含了各种不同的摇滚风格(山地.朋克.乡村.流行.硬摇.金属. ...
- 四.jQuery源码解析之jQuery.fn.init()的参数解析
从return new jQuery.fn.init( selector, context, rootjQuery )中可以看出 参数selector和context是来自我们在调用jQuery方法时 ...
- jQuery构造函数分析
在我的上一篇文章里面 阐述了jQuery的大致框架,知道了所有代码都是写在了一个自调用匿名函数里面,并且传入了window对象,源码是这样的: (function( window, undefined ...
- jQuery 源码分析 8: 回头看jQuery的构造器(jQuery.fn,jQury.prototype,jQuery.fn.init.prototype的分析)
在第一篇jQuery源码分析中,简单分析了jQuery对象的构造过程,里面提到了jQuery.fn.jQuery.prototype.jQuery.fn.init.prototype的关系. 从代码中 ...
- jQuery 源码分析2: jQuery.fn.init
//jQuery.fn.intit 中使用到的外部变量: // 判断是否为HTML标签或#id rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w ...
随机推荐
- 【解决】Word 在试图打开文件时遇到错误 请尝试下列方法:* xxx * xxx * xxx
有好几种情况,我先说我的这个情况 1.word设置不当导致 看图: 然后就能打开了~ 2.word格式问题,比如原来是doc,被人手动改成docx~~~ 解决方法:改回来 3.word版本不兼容,比如 ...
- Sql Server系列:键和约束
1 约束的类型 约束可以分为3大类:实体约束.域约束和参照完整性约束. 1.1 实体约束 实体约束都是关于比较行的,实体约束并不关心整体列中的数据,它只对特定行感兴趣. 1.2 域约束 域约束处理一个 ...
- sizzle分析记录:getAttribute和getAttributeNode
部分IE游览器下无法通过getAttribute取值? <form name="aaron"> <input type="text" name ...
- 《JS设计模式笔记》 2,简单工厂模式
<script type="text/javascript"> //简单工厂模式 //定义:由一个方法来决定到底要创建哪个类的实例,而这些实例经常拥有相同的接口.其实例 ...
- 创建第二个 vlan network "vlan101" - 每天5分钟玩转 OpenStack(96)
前面我们创建了 vlan100,并部署了 instance,今天将继续创建第二个 vlan network "vlan101". subnet IP 地址为 172.16.101. ...
- ASP.NET MVC之持久化TempData及扩展方法(十三)
前言 之前在开始该系列之前我们就讲述了在MVC中从控制器到视图传递数据的四种方式,但是还是存在一点问题,本节就这个问题进行讲述同时进行一些练习来看看MVC中的扩展方法. 话题 废话不必多说,我们直接进 ...
- 安装Ubuntu时分区选择
最近购买来一台二手笔记本.型号是:Dell Latitude D520.回来之后就装上来Ubuntu12.04,开始是安装的UbuntuKylin 13.04.不知道是机器配置不行,还是本身系统有点卡 ...
- 基础知识javascript--事件
群里有一个小伙伴在处理事件监听函数的时候,遇到了一点问题,正好我比较空闲,于是帮他指出了代码中的问题,顺便整理一下,方便以后遇到类似问题的伙伴们有一个参考. 这是一个很简单的问题,对于基础知识比较杂实 ...
- Sublime Text3下的markdown插件的安装及配置
Sublime Text3下的markdown插件的安装及配置 安装准备--安装Package Control 安装MarkdownEditing 安装Markdown Preview或OmniMar ...
- 如何使用SOIL在VS2012的 C++环境下显示图片
先看下效果. 这是一个很无聊的功能....首先说下,我做这个功能的初衷并不是为了实现在控制台中显示图片...(这貌似很无聊) 而是因为自己想做用C做一个游戏:http://q.cnblogs.com/ ...