为什么可以像数组一样查询jQuery(’div’)?

我有另外一个关于jQuery架构的问题。 $('div')构造一个新的jQuery对象:

 $('div') instanceof jQuery; // true 

我想知道为什么有可能像数组一样查询它,虽然它不是一个数组?

 $('div')[0]; // returns the first div in the document as a DOM node. $.isArray($('div')); // false 

我只是喜欢这种语法,看起来很干净! 我还注意到这会将DOM节点作为数组返回:

 console.log($('div')); 

有人可以解释一下如何将这种行为实现到我自己的对象中吗?


我自己的方法是用这样的方法创建一个数组:

 var a = ['a', 'b', 'c']; a.method = function(){ return 'test'; }; a; // ['a', 'b', 'c'] a[0]; // 'a' a.method(); // 'test' 

然而,这似乎不是jQuery的方式,因为这实际上是一个数组:

 $.isArray(a); // true 

我想知道jQuery如何学习这个,看看它是否比我的更好。

一个jQuery对象就是我们所说的Array-like object 。 这意味着,它确实是一个“真正的”对象(事实上,所有“数组”都是ECMAscript中的对象),但它拥有某些属性,使它看起来像一个“真正的”数组。 那些属性是

  • 它作为.length属性
  • 它拥有.splice()方法

这两个事实足以让大多数js引擎控制台将该对象解释为数组。

示例

 var myObject = { }, push = Array.prototype.push; myObject.aNiceFunction = function() { console.log(this); }; push.call( myObject, document.getElementById('foo') ); push.call( myObject, document.getElementById('bar') ); myObject.splice = Array.prototype.splice; 

如果我们现在记录我们的对象

 console.log( myObject ); 

我们得到典型的jQuery’ish结果

 [div#foo, div#bar] 

看到这一点

但我们仍然可以在该对象上调用我们的方法.aNiceFunction() 。 通过使用Array.prototype.push()方法将新元素推送到我们的对象上,ECMAscript将自动为我们索引这些元素。 这是简短描述jQuery引擎盖下发生的事情。

关于ECMAscript中“arrays”的另一个词。 这种语言中没有真正的数组(如果我们忘记了一秒钟的类型化数组 )。 只有Object 。 如果我们有一个inheritance自Array.prototype的对象,我们几乎将它称为数组。 我们剩下要做的就是将.length属性设置为0

jQuery对象是类似于数组的对象。

类数组对象是一个普通对象,它具有与数组相同的属性。
像object这样的数组的length属性设置为正整数,属性名为0 ,… length − 1包含数组对象。

像数组一样处理jQuery对象是duck typing的应用程序。 来自维基百科 :

在使用面向对象编程语言的计算机编程中,duck typing是一种动态类型,其中对象的当前方法和属性集确定有效语义,而不是从特定类或特定接口的实现inheritance。

换句话说, jQuery函数实际返回数组实例并不重要,只要它提供必要的属性( 例如 length ,数字索引)和方法就像数组一样。

JavaScript有其他类似数组的对象。 例如, arguments对象也不是数组,但它具有允许你假装它的属性(如length )。

jQuery对象是“类似数组”的对象。 考虑以下代码:

 document.forms.length; // returns 1; document.forms[0]; // returns a form element. document.forms.join(", "); // throws a type error. this is not an array. typeof document.forms; // returns "object" 

修改你的代码,你可以实现同样的效果:

 var a = { 0: 'a', 1: 'b', 2: 'c', length: 3, method: function() { return "test"; } }; 

我不确定这种“arrays式”的疯狂是什么来自其他答案。 “arrays式”没有标准术语。

这里的实际差异是实际数组与链接列表之间的差异,实际数组是元素的集合,而链接列表是引用的集合。 在参考DOM时,链表被正确地称为节点列表。 这些文章有更多信息:

http://www.mindcracker.com/Story/1016/interview-question-difference-between-linked-list-and-array.aspx

http://www.sitepoint.com/a-collection-is-not-an-array/

http://blog.duruk.net/2011/06/19/nodelists-and-arrays-in-javascript/