2012-01-09 47 views
8

我收到了关于jQuery架构的另一个问题。 $('div')构造一个新jQuery对象:为什么可以像查询数组一样查询jQuery('div')?

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

我想知道为什么它是可以查询它像一个数组,allthough它不是一个数组?

$('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如何做到这一点学习,看看它是否比我更好的解决方案。

+0

可以使用'[]'符号访问* *的任何财产。不仅仅是指数。所以就像'$('div')[0]'一样,你可以执行$('div')['jquery']',这会给你jQuery的版本号。 – 2012-01-09 18:14:10

+0

@amnotiam我知道。但是当我在控制台中打印常用对象时,它们不输出数组。 – 2012-01-09 18:14:53

+0

啊,如果你特别要求控制台的输出,那么它确实就是控制台对你输入的内容做出最好的猜测。 [jAndy的回答](http://stackoverflow.com/a/8793090/1106925)显示了控制台通常会做什么。 – 2012-01-09 18:16:36

回答

10

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

  • 它作为.length财产
  • 它拥有.splice()方法

这两个事实足以大多数 JS引擎 控制台将interpretate对象作为数组。

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] 

See that in action

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

关于ECMAscript中“阵列”的更多词汇。这种语言没有真正的数组(如果我们忘记typed arrays一秒钟)。只有Object。如果我们有一个从Array.prototype继承的对象,我们几乎可以称它为一个数组。我们将要做的所有事情是,将.length属性设置为0

+2

JS引擎不会将任何内容解释为数组。 JS _users_将数据解释为数组。 :) – SLaks 2012-01-09 18:10:52

+0

@SLaks:touchè。我的意思是,它是如何被控制台对象“注销”的。 – jAndy 2012-01-09 18:17:52

+0

这是Firebug/Chrome漂亮打印机(它是JS用户)的功能,而不是JS引擎。 – SLaks 2012-01-09 18:18:32

2

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

类似数组的对象是与数组具有相同属性的普通对象。
状物体的阵列具有length属性设置为正整数,和属性命名01,... length − 1包含数组对象。

0

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"; 
    } 
}; 
+0

'console.log(a)'不打印数组。所以这看起来并不像jQuery那样。顺便说一句,我不是JavaScript初学者,我知道JavaScript对象是如何工作的。 – 2012-01-09 18:18:01

1

像对待一个数组jQuery对象是鸭打字的应用程序。 From Wikipedia

在计算机编程用的面向对象的编程语言, 鸭打字动态类型的风格,其中对象的当前 集的方法和属性来确定有效的语义,而 不是从它的继承特定类别或特定接口的实现。

换句话说,这不是重要的是,jQuery函数实际上返回一个数组实例,只要它提供了必要的性能(例如length,数字索引)和方法行为像阵列。

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

0

我不确定这个“阵列式”的疯狂是来自其他答案。 “阵列式”没有标准术语。

这里的实际区别是实际的数组,它是一个元素集合与一个链接列表(它是一个引用集合)的差异。在参考DOM时,链接列表被适当地称为节点列表。这些articlea有更多的信息:

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/

相关问题