jQuery如何创建Array-Objects?
起初我以为它只是在返回它之前将obj [0],obj [1],obj [2]等分配给jQuery对象,并且手动分配长度。 但不,因为console.log记录数组而不是对象。
我快速浏览了jQuery源码,但由于我不熟悉它,我没有轻易破解它。 jQuery.makeArray
首先弹出,但事实certificate它与我正在寻找的相反,你实际上通过使用它失去了对象方法。
我的第一个猜测是首先启动数组,然后将对象中的所有属性和方法复制到它。
有没有jQuery源代码经验的人对此有明确的答案?
它就像创建一个新函数并为其分配一个新数组一样简单。
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();
jQuery创建所谓的(在ES标准中)类似于数组的对象。 特别是,它们具有长度属性,并且(使用长度属性)它们具有放置在基于整数的索引下的相关项。
它很简单:
var arrayLike = {length: 3, 0:'first', 1:'second', 2:'third'}; Array.prototype.join.call(arrayLike, '|'); // "first|second|third"
如果您查看标准 (15.4.4),特别是Array.prototype
方法,您将在每个方法下看到以下注释:
注意*函数是有意通用的; 它不要求它的这个值是一个Array对象。 因此,它可以转移到其他类型的对象以用作方法。 *函数是否可以成功应用于宿主对象是依赖于实现的。
如果你看一下这些算法的描述,他们几乎只是使用length属性迭代对象(在我们的例子中是一个类似数组的对象)并访问这些基于整数的键背后的值。 因此,它们是通用的,可以处理具有相关属性的常规js对象。
基本上这就是所有jQuery都做的(如果我没记错的话,建筑是在sizzle,jquery的css选择器引擎中完成的)。 您可以通过各种方式测试/certificate它。 例如,标准的js数组在缩短length属性时会执行一些魔术,但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
所以jquery的makeArray
转换了类似jquery数组的对象,并使它成为一个实际的本机js数组,但正如你所说,它没有附加所有的jquery方法。
至于它出现在控制台中的原因,我提到了这个优秀的答案: 是什么让Firebug / Chrome控制台将自定义对象视为一个数组? 这解释了length
属性和splice
function的存在使它在大多数控制台中看起来像一个数组。 如前所述,在FF4的Web控制台中并非如此,它只是向您展示它不是本机js数组。 有趣的是, splice
function实际上并不需要工作,只是存在,并且是一个function。 例如:
>> console.log({length:2,0:'some',1:'thing',splice:new Function}); ["some", "thing"]
以下简单的代码,介绍如何使用本机JavaScript数组转换jQuery选择器返回的数组:
var $arr = $('option'); // assuming three options var arr = Array.apply(null, $arr); // arr contains [option, option]
考虑以下代码的HTML: