什么是 jQuery 对象?
$()
orjQuery()
函数返回一个jQuery
对象。它Array
不是 a 也不是 a NodeList
,也不是以任何方式派生自其中任何一个。它是Object
使用构造函数创建的jQuery
(实际上是jQuery.fn.init()
函数)。这个对象非常像任何其他Object
使用创建new SomeConstructor()
的对象,甚至是一个普通的对象字面量。
当你打电话$()
或jQuery()
没有new
接线员时,它会自动new
为你做一个:
jQuery = function( selector, context ) {
// The jQuery object is actually just the init
// constructor 'enhanced'
return new jQuery.fn.init( selector, context, rootjQuery );
},
该jQuery
对象有点“类似数组”,因为它具有带有数字索引的属性和一个.length
属性,但这些只是在 jQuery 代码中直接在对象中设置的属性。它还具有许多来自其原型的属性和方法,即jQuery.fn
or jQuery.prototype
(jQuery.fn
仅仅是对 的引用jQuery.prototype
;它们是同一个对象。)
您可以在使用时包装 DOM 元素$(element)
的 jQuery 代码中看到一个示例:
// HANDLE: $(DOMElement)
} else if ( selector.nodeType ) {
this.context = this[0] = selector;
this.length = 1;
return this;
} ...
在这段代码中,selector
实际上是一个 DOM 元素,代码将该元素存储在this[0]
并设置this.length
为1
. 这就是您可以使用[0]
and的.length
原因,因为该对象具有已明确设置的这些属性。
为什么 jQuery 对象会像数组一样显示?
这里有一些魔力,但魔力在于 Firebug 和 Chrome 开发者工具。他们都寻找两个特定的属性来决定将对象显示为数组:
- 一个
length
属性,可以是数字或包含数字的字符串。
- 一个
splice
属性,它是一个函数。
如果对象同时具有这两个属性,则将其显示为数组。
您可以通过将以下行粘贴到 Chrome DevTools 或 Firebug 中来对此进行测试:
({ splice:function(){}, length:0 })
铬显示:
[]
萤火虫显示:
Object[ ]
删除任一属性,它将显示为一个对象。
这些属性是在对象本身还是在它的原型中并不重要。您可以将此代码粘贴到任一控制台中,它将显示与上述代码相同的类似数组的符号:
function A(){}; A.prototype = { splice:function(){}, length:0 }; new A;
您可以将元素添加到“数组”中:
({ splice:function(){}, length:1, 0:'test' })
现在 Chrome 显示:
["test"]
和 Firebug 显示:
Object[ "test" ]
请注意,Firebug 显示与实际显示的Array
. Firebug 将该Object
前缀放在类似数组的显示前面,让您知道它不是实际的Array
.
它也在 jQuery 对象上执行此操作。如果您输入:
$(document.body)
萤火虫显示:
Object[ body ]
您可以单击单词Object
以获取 jQuery 对象的完整对象样式显示,而不是类似数组的显示。
Chrome 没有这种区别。它以相同的方式显示一个Array
或类似数组。Object
于是就有了魔力。它在 jQuery 中真的没有什么特别之处,只是它返回的对象确实具有length
andsplice
属性。该splice()
方法位于原型上,length
属性可能来自原型(对于空“数组”)或更常见的是来自 jQuery 对象本身。
这两个属性触发了真正的魔力:DevTools 和 Firebug 中的 hack,试图为这些对象提供更有用的显示。
吹牛的权利 :-)
一点历史琐事:我实际上负责 jQuery 架构的这一部分。2006 年初 jQuery 的第一个版本并不是这样工作的。jQuery 对象没有.length
and [0]
,[1]
等属性。相反,它有一个自己的“私有”数组,您必须使用.get(n)
它从该数组中获取值。
我认为直接以类似数组的方式访问元素会更方便,并想出了设置.length
、[0]
、[1]
等属性的想法,这样它就可以像只读数组一样工作。