在我的上一篇随笔里面分析了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参数分析(一)的更多相关文章

  1. jQuery构造函数init参数分析(三)

    分析完了字符串情况剩下的就不多了. 5.参数selector是函数 这个就是很容易想到了,首先说一下dom加载.我们通常在head里面写脚本的时候需要等待文档加载在进行处理,js是这么写的 windo ...

  2. jQuery构造函数init参数分析(二)

    接着上一篇随笔讨论. 如果selector是其他字符串情况就比较多了比较复杂了 // Handle HTML strings if ( typeof selector === "string ...

  3. 浅谈jQuery构造函数

    $()函数到底做的什么 jQuery在前端领域路人皆知,对于一向喜欢玩js的博主来说,虽然能力有限,但是还是很喜欢研究他的做为.那么一个简单的美元符号$与一对常见的()括号,jQuery底层到底做了哪 ...

  4. jQuery学习笔记之jQuery.fn.init()的参数分析

    这篇文章主要介绍了jQuery.fn.init()的参数分析,需要的朋友可以参考下   从return new jQuery.fn.init( selector, context, rootjQuer ...

  5. jQuery分析(3) - jQuery.fn.init

    1.前言 上一篇jQuery分析(2)中了解了jQuery库的骨架实现原理,这就好比摇滚音乐,摇滚音乐不是某种音乐他就像一个音乐盒子,里面包含了各种不同的摇滚风格(山地.朋克.乡村.流行.硬摇.金属. ...

  6. 四.jQuery源码解析之jQuery.fn.init()的参数解析

    从return new jQuery.fn.init( selector, context, rootjQuery )中可以看出 参数selector和context是来自我们在调用jQuery方法时 ...

  7. jQuery构造函数分析

    在我的上一篇文章里面 阐述了jQuery的大致框架,知道了所有代码都是写在了一个自调用匿名函数里面,并且传入了window对象,源码是这样的: (function( window, undefined ...

  8. jQuery 源码分析 8: 回头看jQuery的构造器(jQuery.fn,jQury.prototype,jQuery.fn.init.prototype的分析)

    在第一篇jQuery源码分析中,简单分析了jQuery对象的构造过程,里面提到了jQuery.fn.jQuery.prototype.jQuery.fn.init.prototype的关系. 从代码中 ...

  9. jQuery 源码分析2: jQuery.fn.init

    //jQuery.fn.intit 中使用到的外部变量: // 判断是否为HTML标签或#id rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w ...

随机推荐

  1. 【解决】Word 在试图打开文件时遇到错误 请尝试下列方法:* xxx * xxx * xxx

    有好几种情况,我先说我的这个情况 1.word设置不当导致 看图: 然后就能打开了~ 2.word格式问题,比如原来是doc,被人手动改成docx~~~ 解决方法:改回来 3.word版本不兼容,比如 ...

  2. Sql Server系列:键和约束

    1 约束的类型 约束可以分为3大类:实体约束.域约束和参照完整性约束. 1.1 实体约束 实体约束都是关于比较行的,实体约束并不关心整体列中的数据,它只对特定行感兴趣. 1.2 域约束 域约束处理一个 ...

  3. sizzle分析记录:getAttribute和getAttributeNode

    部分IE游览器下无法通过getAttribute取值? <form name="aaron"> <input type="text" name ...

  4. 《JS设计模式笔记》 2,简单工厂模式

    <script type="text/javascript"> //简单工厂模式 //定义:由一个方法来决定到底要创建哪个类的实例,而这些实例经常拥有相同的接口.其实例 ...

  5. 创建第二个 vlan network "vlan101" - 每天5分钟玩转 OpenStack(96)

    前面我们创建了 vlan100,并部署了 instance,今天将继续创建第二个 vlan network "vlan101". subnet IP 地址为 172.16.101. ...

  6. ASP.NET MVC之持久化TempData及扩展方法(十三)

    前言 之前在开始该系列之前我们就讲述了在MVC中从控制器到视图传递数据的四种方式,但是还是存在一点问题,本节就这个问题进行讲述同时进行一些练习来看看MVC中的扩展方法. 话题 废话不必多说,我们直接进 ...

  7. 安装Ubuntu时分区选择

    最近购买来一台二手笔记本.型号是:Dell Latitude D520.回来之后就装上来Ubuntu12.04,开始是安装的UbuntuKylin 13.04.不知道是机器配置不行,还是本身系统有点卡 ...

  8. 基础知识javascript--事件

    群里有一个小伙伴在处理事件监听函数的时候,遇到了一点问题,正好我比较空闲,于是帮他指出了代码中的问题,顺便整理一下,方便以后遇到类似问题的伙伴们有一个参考. 这是一个很简单的问题,对于基础知识比较杂实 ...

  9. Sublime Text3下的markdown插件的安装及配置

    Sublime Text3下的markdown插件的安装及配置 安装准备--安装Package Control 安装MarkdownEditing 安装Markdown Preview或OmniMar ...

  10. 如何使用SOIL在VS2012的 C++环境下显示图片

    先看下效果. 这是一个很无聊的功能....首先说下,我做这个功能的初衷并不是为了实现在控制台中显示图片...(这貌似很无聊) 而是因为自己想做用C做一个游戏:http://q.cnblogs.com/ ...