jQuery返回的对象的实际类型是什么

时间:2013-09-06 00:55:37

标签: javascript jquery object

就像$本身不仅仅是一个用户定义的对象(它的基础是一个函数,这就是为什么你可以在它上面使用()运算符并继承所有函数的原因来自Function.prototype)所谓的jQuery对象的实际Javascript type是什么?

它必须是标准的类似数组的对象之一,因为你可以在它上面使用[]运算符,这在IE8中甚至不能用于字符串(不,你不能,不是在对象String上。你可以在它们被装箱之前对字符串文字进行处理。) 所以再次,它不是一个用户定义的对象(NB没有jQuery对象这样的东西,它在原始的javascript中写入了一行。)我感觉它是NodeList(或者在没有NodeList的浏览器中等效。)

您可能已经注意到这一点的原因是您已经为Array原型添加了方法,并且您发现jQuery找到的一组节点上不存在该函数!

所有与jQuery密切相关的人都可以与我分享这个较低级别的信息吗?或者是否有一个简短的,详尽的Javascript中类似数组的对象列表,我可以测试jQuery对象,直到找到它自己是哪一个?


我问这个的原因,而不是假设jQuery只是添加元素到对象,使用索引作为属性名称(即obj[0] = x;)是因为Chrome开发工具和Firebug如何显示它们。 /> dev tools displaying Array, jQuery and Array-like objects
这显示了开发工具显示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

2 个答案:

答案 0 :(得分:7)

什么是jQuery对象?

$()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.fnjQuery.prototypejQuery.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的原因,因为该对象具有明确设置的这些属性。

为什么jQuery对象会像数组一样显示?

这里涉及一些魔术,但神奇之处在于Firebug和Chrome开发者工具。它们都寻找两个特定属性来决定显示一个对象,就好像它是一个数组:

  1. length属性,可以是数字,也可以是包含数字的字符串。
  2. 作为函数的splice属性。
  3. 如果对象同时具有这两个属性,则它将显示为数组。

    您可以将以下行粘贴到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中并没有什么特别之处,除了它返回的对象确实具有lengthsplice属性。 splice()方法位于原型上,length属性可能来自原型(对于空“数组”),或者更常来自jQuery对象本身。

    这两个属性触发真正的魔力:DevTools和Firebug中的黑客试图为这些对象提供更有用的显示。

    Bragging权利: - )

    一些历史琐事:我实际上负责jQuery架构的这一部分。 2006年初jQuery的第一个版本没有像这样工作。 jQuery对象没有.length[0][1]等属性。相反,它有一个自己的“私有”数组,你必须使用.get(n)从该数组中获取值。

    我认为对元素进行直接的类似数组的访问会更方便,并想出了设置.length[0][1]等属性的想法所以它会像只读数组一样工作。

答案 1 :(得分:-2)

我的理解是Array的一个子类,它继承自Array Class并且有自己的方法

以上变化:

它不是Array的子​​类。但它是从Array制作的,但是在创建了Array对象之后,jQuery用jQuery改变了对象原型自己的原型,最后它变成了jQuery对象,它是类似Array的对象。