就像$
本身不仅仅是一个用户定义的对象(它的基础是一个函数,这就是为什么你可以在它上面使用()
运算符并继承所有函数的原因来自Function.prototype
)所谓的jQuery对象的实际Javascript type
是什么?
它必须是标准的类似数组的对象之一,因为你可以在它上面使用[]
运算符,这在IE8中甚至不能用于字符串(不,你不能,不是在对象String
上。你可以在它们被装箱之前对字符串文字进行处理。)
所以再次,它不是一个用户定义的对象(NB没有jQuery
对象这样的东西,它在原始的javascript中写入了一行。)我感觉它是NodeList
(或者在没有NodeList
的浏览器中等效。)
您可能已经注意到这一点的原因是您已经为Array
原型添加了方法,并且您发现jQuery找到的一组节点上不存在该函数!
所有与jQuery密切相关的人都可以与我分享这个较低级别的信息吗?或者是否有一个简短的,详尽的Javascript中类似数组的对象列表,我可以测试jQuery对象,直到找到它自己是哪一个?
我问这个的原因,而不是假设jQuery只是添加元素到对象,使用索引作为属性名称(即obj[0] = x;
)是因为Chrome开发工具和Firebug如何显示它们。 />
这显示了开发工具显示Array,jQuery和类似数组的对象,并且jQuery正在做的事情背后至少有一些魔力。
修改
这不是NodeList
。如果它有帮助;在Chrome中检查它会显示它是jQuery.fn.jQuery.init[0]
类型,其中__proto__
将自己描述为Object[0]
(其中包含所有jquery方法)。任何解释jQuery正在做什么以及如何做的人都会非常感谢。我现在要看看jQuery的源代码。
至于图像,它不仅仅是被覆盖的.toString()
。
$('').toString == Object.prototype.toString //true
$('').toString == Array.prototype.toString //false
答案 0 :(得分:7)
$()
或jQuery()
函数返回jQuery
个对象。它不是Array
而不是NodeList
,并且不以任何方式从这两者中衍生出来。它是使用Object
构造函数(实际上是jQuery
函数)创建的jQuery.fn.init()
。此对象非常类似于使用Object
创建的任何其他new SomeConstructor()
,甚至是普通对象文字。
如果您在没有$()
运算符的情况下致电jQuery()
或new
,则会automatically does a new
for you:
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
或jQuery.prototype
(jQuery.fn
仅仅是对jQuery.prototype
的引用;它们是同一个对象。)
您可以在jQuery code that wraps a DOM element when you use $(element)
中找到相关示例:
// HANDLE: $(DOMElement)
} else if ( selector.nodeType ) {
this.context = this[0] = selector;
this.length = 1;
return this;
} ...
在这段代码中,selector
实际上是一个DOM元素,代码将该元素存储在this[0]
中,并将this.length
设置为1
。这就是您可以使用[0]
和.length
的原因,因为该对象具有明确设置的这些属性。
这里涉及一些魔术,但神奇之处在于Firebug和Chrome开发者工具。它们都寻找两个特定属性来决定显示一个对象,就好像它是一个数组:
length
属性,可以是数字,也可以是包含数字的字符串。splice
属性。如果对象同时具有这两个属性,则它将显示为数组。
您可以将以下行粘贴到Chrome DevTools或Firebug中进行测试:
({ splice:function(){}, length:0 })
Chrome显示:
[]
Firebug显示:
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)
Firebug显示:
Object[ body ]
您可以单击单词Object
以获取jQuery对象的完整对象样式显示,而不是类似数组的显示。
Chrome没有做出这种区分;它以相同的方式显示Array
或类似数组的Object
。
所以有魔力。它在jQuery中并没有什么特别之处,除了它返回的对象确实具有length
和splice
属性。 splice()
方法位于原型上,length
属性可能来自原型(对于空“数组”),或者更常来自jQuery对象本身。
这两个属性触发真正的魔力:DevTools和Firebug中的黑客试图为这些对象提供更有用的显示。
一些历史琐事:我实际上负责jQuery架构的这一部分。 2006年初jQuery的第一个版本没有像这样工作。 jQuery对象没有.length
和[0]
,[1]
等属性。相反,它有一个自己的“私有”数组,你必须使用.get(n)
从该数组中获取值。
我认为对元素进行直接的类似数组的访问会更方便,并想出了设置.length
,[0]
,[1]
等属性的想法所以它会像只读数组一样工作。
答案 1 :(得分:-2)
我的理解是Array的一个子类,它继承自Array Class并且有自己的方法
以上变化:
它不是Array的子类。但它是从Array制作的,但是在创建了Array对象之后,jQuery用jQuery改变了对象原型自己的原型,最后它变成了jQuery对象,它是类似Array的对象。