3

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

它必须是标准的类数组对象之一,因为您可以在其上使用[]运算符,这在 IE8 中甚至不能对字符串执行(不,您不能,不是在 Object 上String。您可以在字符串装箱前的文字)。
再说一遍,它不是用户定义的对象(注意,没有对象之类的东西jQuery,它是用原始 javascript 编写的)。我感觉它是 a NodeList(或在没有的浏览器中等效NodeList)。

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

那么,有足够了解 jQuery 的人与我分享这些较低级别的信息吗?或者是否有一个简短的、详尽的 Javascript 中类似数组的对象列表,我可以测试 jQuery 对象,直到我发现它是我自己?


我之所以问这个问题,而不是假设 jQuery 只是向对象添加元素,而是使用索引作为属性名称 (Ie obj[0] = x;),是因为 Chrome 开发工具和 Firebug 是如何显示它们的。
显示数组、jQuery 和类数组对象的开发工具
这显示了显示数组、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
4

2 回答 2

7

什么是 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.fnor 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.length1. 这就是您可以使用[0]and的.length原因,因为该对象具有已明确设置的这些属性。

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

这里有一些魔力,但魔力在于 Firebug 和 Chrome 开发者工具。他们都寻找两个特定的属性来决定将对象显示为数组:

  1. 一个length属性,可以是数字或包含数字的字符串。
  2. 一个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 中真的没有什么特别之处,只是它返回的对象确实具有lengthandsplice属性。该splice()方法位于原型上,length属性可能来自原型(对于空“数组”)或更常见的是来自 jQuery 对象本身。

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

吹牛的权利 :-)

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

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

于 2013-09-06T01:44:03.033 回答
-2

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

上面的变化:

它不是 Array 的子类。但它是由Array构成的,但是在Array对象创建之后,jQuery用jQuery自己的原型改变了对象原型,最终变成了jQuery对象,也就是类Array对象。

于 2013-09-06T01:00:43.283 回答