jQuery对象如何模仿数组?

时间:2021-03-01 23:08:19

jQuery objects act like arrays without polluting native prototypes. How is this achieved?

jQuery对象就像数组一样,不会污染原生原型。这是如何实现的?

I know it's not just objects with numeric keys - so perhaps it's just a matter of providing the respective methods (something like jQuery.prototype.indexOf = Array.prototype.indexOf).

我知道这不仅仅是带有数字键的对象 - 所以也许只是提供相应的方法(类似于jQuery.prototype.indexOf = Array.prototype.indexOf)。

I've googled and looked at the source, but couldn't find a definitive answer.

我用Google搜索并查看了源代码,但未找到明确的答案。

2 个解决方案

#1


26  

Although jQuery objects act like arrays, they are actually only array-like objects. An array-like object is an object using numeric keys and having a length property - that is the minimum needed for compatibility with the native array methods.

虽然jQuery对象就像数组一样,但它们实际上只是类似于数组的对象。类数组对象是使用数字键并具有length属性的对象 - 这是与本机数组方法兼容所需的最小值。

Because jQuery objects are only array-like and not actual Array objects, native array operations (like indexOf or reverse) cannot be called directly. You can use Array.prototype though, or extend jQuery's functionality.

因为jQuery对象只是类似数组而不是实际的Array对象,所以不能直接调用本机数组操作(如indexOf或reverse)。您可以使用Array.prototype,或者扩展jQuery的功能。

$('div').reverse(); // TypeError: $("div").reverse is not a function

// we can use Array.prototype though
Array.prototype.reverse.apply($('div'));

// or we can extend jQuery very easily
$.fn.reverse = Array.prototype.reverse;
$('div').reverse(); // now it works!

You are correct in your assumption that Firebug does not include any special-casing for formatting jQuery objects. A quick search reveals a relevant post on the Firebug mailing list. Assuming the information is still correct (the post is from January) Firebug will format an object as an array if it has a finite length and a splice method.

假设Firebug不包含用于格式化jQuery对象的任何特殊外壳,这是正确的。快速搜索显示Firebug邮件列表中的相关帖子。假设信息仍然正确(帖子是从1月开始),Firebug会将对象格式化为数组(如果它具有有限长度和拼接方法)。

JQuery fulfils both of these criteria, but their implementation of splice is nothing more than a direct copy of the native Array method. It is undocumented, which means it's either only for internal use, or perhaps added solely for the purpose of tricking Firebug into formatting jQuery objects nicely.

JQuery满足这两个标准,但它们的splice实现只不过是本机Array方法的直接副本。它没有文档,这意味着它只是为了内部使用,或者可能只是为了欺骗Firebug很好地格式化jQuery对象。

#2


5  

Look in jquery code (development), line 139:

查看jquery代码(开发),第139行:

// Force the current matched set of elements to become
// the specified array of elements (destroying the stack in the process)
// You should use pushStack() in order to do this, but maintain the stack
setArray: function( elems ) {
    // Resetting the length to 0, then using the native Array push
    // is a super-fast way to populate an object with array-like properties
    this.length = 0;
    Array.prototype.push.apply( this, elems );
        return this;
},

This is because any result of jquery queries is array.

这是因为jquery查询的任何结果都是数组。

#1


26  

Although jQuery objects act like arrays, they are actually only array-like objects. An array-like object is an object using numeric keys and having a length property - that is the minimum needed for compatibility with the native array methods.

虽然jQuery对象就像数组一样,但它们实际上只是类似于数组的对象。类数组对象是使用数字键并具有length属性的对象 - 这是与本机数组方法兼容所需的最小值。

Because jQuery objects are only array-like and not actual Array objects, native array operations (like indexOf or reverse) cannot be called directly. You can use Array.prototype though, or extend jQuery's functionality.

因为jQuery对象只是类似数组而不是实际的Array对象,所以不能直接调用本机数组操作(如indexOf或reverse)。您可以使用Array.prototype,或者扩展jQuery的功能。

$('div').reverse(); // TypeError: $("div").reverse is not a function

// we can use Array.prototype though
Array.prototype.reverse.apply($('div'));

// or we can extend jQuery very easily
$.fn.reverse = Array.prototype.reverse;
$('div').reverse(); // now it works!

You are correct in your assumption that Firebug does not include any special-casing for formatting jQuery objects. A quick search reveals a relevant post on the Firebug mailing list. Assuming the information is still correct (the post is from January) Firebug will format an object as an array if it has a finite length and a splice method.

假设Firebug不包含用于格式化jQuery对象的任何特殊外壳,这是正确的。快速搜索显示Firebug邮件列表中的相关帖子。假设信息仍然正确(帖子是从1月开始),Firebug会将对象格式化为数组(如果它具有有限长度和拼接方法)。

JQuery fulfils both of these criteria, but their implementation of splice is nothing more than a direct copy of the native Array method. It is undocumented, which means it's either only for internal use, or perhaps added solely for the purpose of tricking Firebug into formatting jQuery objects nicely.

JQuery满足这两个标准,但它们的splice实现只不过是本机Array方法的直接副本。它没有文档,这意味着它只是为了内部使用,或者可能只是为了欺骗Firebug很好地格式化jQuery对象。

#2


5  

Look in jquery code (development), line 139:

查看jquery代码(开发),第139行:

// Force the current matched set of elements to become
// the specified array of elements (destroying the stack in the process)
// You should use pushStack() in order to do this, but maintain the stack
setArray: function( elems ) {
    // Resetting the length to 0, then using the native Array push
    // is a super-fast way to populate an object with array-like properties
    this.length = 0;
    Array.prototype.push.apply( this, elems );
        return this;
},

This is because any result of jquery queries is array.

这是因为jquery查询的任何结果都是数组。