jQuery如何创建Array-Objects?

时间:2011-10-04 16:57:24

标签: javascript jquery arrays object

起初我认为只是在返回之前将obj [0],obj [1],obj [2]等分配给jQuery对象,并且长度为手动分配。但不,因为console.log记录了一个数组,而不是一个对象。

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

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

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

3 个答案:

答案 0 :(得分: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都做了(如果我没记错的话,构建是在sizzle,jquery的css选择器引擎中完成的)。您可以通过各种方式测试/证明它。例如,标准的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

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"]

答案 1 :(得分: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/

答案 2 :(得分:5)

以下简单的代码,介绍如何使用本机JavaScript数组转换jQuery选择器返回的数组:

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>