Javascript 为什么可以像数组一样查询jQuery(';div';)呢?

Javascript 为什么可以像数组一样查询jQuery(';div';)呢?,javascript,jquery,Javascript,Jquery,我还有一个关于jQuery架构的问题$('div')构造一个新的jQuery对象: $('div') instanceof jQuery; // true 我想知道为什么可以像数组一样查询它,尽管它不是数组 $('div')[0]; // returns the first div in the document as a DOM node. $.isArray($('div')); // false 我只是喜欢这个语法,它看起来很干净!我还注意到这会将DOM节点作为数组返回: consol

我还有一个关于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'));
$.isArray(a); // true
有人能解释一下如何在我自己的对象上实现这种行为吗


我自己的方法是使用以下方法制作数组:

var a = ['a', 'b', 'c'];
a.method = function(){ return 'test'; };
a; // ['a', 'b', 'c']
a[0]; // 'a'
a.method(); // 'test'
但是,jQuery似乎不是这样做的,因为它实际上是一个数组:

console.log($('div'));
$.isArray(a); // true

我想知道jQuery是如何做到这一点的,以了解它是否比我的解决方案更好。

jQuery对象是类似数组的对象

类似数组的对象是具有与数组相同属性的普通对象。

类数组对象的
length
属性设置为正整数,属性名为
0
1
<代码>长度− 1包含数组对象。

jQuery对象就是我们所说的
类数组对象
。这意味着,它确实是一个“真”对象(实际上,所有“数组”都是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中的“数组”还有一个词。这种语言中没有真正的数组(如果我们暂时忘记的话)。只有
对象
。如果我们有一个从
Array.prototype
继承的对象,我们几乎可以称之为Array。我们剩下要做的就是,将
.length
属性设置为
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";
    }
};

将jQuery对象视为数组是duck类型的一个应用程序:

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

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

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

我不确定其他答案中的这种“类似数组”的疯狂是什么。“类数组”没有标准术语

这里的实际区别是实际数组(元素集合)与链表(引用集合)之间的区别。在DOM中,链表被恰当地称为节点列表。这些条款A提供了更多信息:


JS引擎不会将任何内容解释为数组。JS用户将事物解释为数组。:)@渣:摸一下。我的意思是,它是如何被控制台对象“注销”的。这是Firebug/Chrome的漂亮打印机(是JS用户)的功能,而不是JS引擎。您可以使用
[]
符号访问任何属性。不仅仅是指数。所以就像
$('div')[0]
,您可以执行
$('div')['jquery']
,这将为您提供jquery版本号。@amnotiam我知道。但是当我在控制台中打印普通对象时,它们不会输出数组。啊,如果你特别询问控制台输出,那么它实际上只是控制台对你给它的内容做出了最好的猜测。显示控制台通常执行的操作。示例:
console.log({“2”:“foo”,splice:function(){},length:2})
显然不是正在记录的数组,但显示为
[未定义,未定义,“foo”]
控制台的可能副本。log(a)打印的是对象而不是数组。所以jQuery似乎不是这样做的。顺便说一下,我不是JavaScript初学者,我知道JavaScript对象是如何工作的。