2011-10-04 98 views
6

起初我以为它只是在返回之前将obj [0],obj [1],obj [2]等分配给jQuery对象,并且指定的长度为,手动已分配。但是,不,因为console.log记录一个数组而不是一个对象。jQuery如何创建数组对象?

我快速浏览了jQuery源代码,但由于我不熟悉它,所以我没有轻易破解它。 jQuery.makeArray首先弹出,但事实证明与我正在寻找的相反,实际上通过使用它丢失了对象方法。

我的第一个猜测是首先启动数组,然后将所有的属性和方法从对象复制到它。

有没有人有jQuery源代码的经验有明确的答案呢?

+0

它被认为与'NodeList'工作方式类似于数组,但不是。 – BoltClock

+0

什么是数组对象?你怎么知道它记录一个数组而不是一个对象? –

回答

5

这是为创建一个新的功能,并分配一个新的数组作为它的原型一样简单。

function ArrayLike() {} 
ArrayLike.prototype = []; 

因此,例如:

function ArrayLike() {} 
ArrayLike.prototype = []; 
ArrayLike.prototype.fromArray = function(arr) { 
    for(var i = 0; i < arr.length; i++) 
     this.push(arr[i]); 
}; 
ArrayLike.prototype.foo = function() { 
    console.log("foo", this); 
}; 

var a = new ArrayLike(); 
a.fromArray([1, 2]); 
console.log(a); 
a.foo(); 

http://jsfiddle.net/Xeon06/fUgaf/

+0

这是非常光滑的。我会问一个关于这个简约版本的问题。谢谢。 – Manngo

13

jQuery创建所谓的(在ES标准中)类似数组的对象。特别是,他们有一个长度属性,并且(使用长度属性),他们有相关的项目放置在基于整数的索引下。

很简单:

var arrayLike = {length: 3, 0:'first', 1:'second', 2:'third'}; 
Array.prototype.join.call(arrayLike, '|'); // "first|second|third" 

如果你看一看the standard(15.4.4),特别是Array.prototype方法,你会看到在每一个下面的注释:

注* *函数是有意通用的;它不要求 它的这个值是一个Array对象。因此可以将其转换为其他类型的对象以用作方法。 *函数是否可以将 成功应用于主机对象取决于实现。

如果你看看这些算法的描述,他们几乎只使用length属性来遍历对象(在我们的情况下,阵列状对象)和访问背后那些基于整数的值键。出于这个原因,它们是通用的,并且处理具有相关属性的常规js对象。本质上,这就是所有的jQuery(如果我没有记错的话,建设是在嘶嘶声,jQuery的css选择器引擎完成)。你可以用多种方法来测试/证明它。例如,一个标准的js阵列执行一些魔术当长度属性被缩短,但jQuery对象不会:

var arr = [1,2,3], $arr = $('div'); // assuming three divs 
arr.length=2; arr[2]; // undefined 
$arr.length=2; $arr[2]; // still references the div 

http://jsfiddle.net/cnkB9/

所以jquery的makeArray转换jquery的阵列状物体,并且使它成为一个真正的本地js数组,但正如你所说,然后它没有附加所有的jquery方法。

至于为什么在控制台中显示出来,我指的是这个优秀的答案:What makes Firebug/Chrome console treat a custom object as an array?解释了length财产的存在和splice功能,允许它在控制台看起来像一个数组。如前所述,FF4的Web控制台并不是这种情况,它只是告诉你它不是本地的js数组。有趣的是,splice函数实际上并不需要工作,只是存在,并且是一个函数。例如:

>> console.log({length:2,0:'some',1:'thing',splice:new Function}); 
["some", "thing"] 
5

如何变换由jQuery选择在操作与天然JavaScript数组返回阵列下面的简单代码:

var $arr = $('option'); // assuming three options 
var arr = Array.apply(null, $arr); 
// arr contains [option, option] 

考虑到以上代码的以下HTML:

<html> 
    <head> 
     <script type="text/javascript" src="jquery-1.5.2.min.js"></script> 
    </head> 
    <body> 
     <select id="addSelection"> 
      <option value="Original Value">Original Value</option> 
      <option value="Two Value">Value two</option> 
      <option value="Three Value">Value three</option> 
     </select> 

     <br /> 

     <input id="btn" type="button" value="Changes" /> 
    </body> 
</hmtl>