Как объекты jQuery имитируют массивы?

Объекты jQuery действуют как массивы без загрязнения собственных прототипов. Как это достигается?

Я знаю это не только объекты с числовыми клавишами - так что, возможно, это просто вопрос предоставления соответствующих методов (что-то вроде jQuery.prototype.indexOf = Array.prototype.indexOf).

Я искал googled и смотрел на источник, но не смог найти окончательного ответа.

Ответы

Ответ 1

Хотя объекты jQuery действуют как массивы, они фактически являются только подобными массиву объектами. Объект, подобный массиву, является объектом, использующим числовые ключи и обладающим свойством length - минимальным, необходимым для совместимости с методами родного массива..

Поскольку объекты 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!

Вы правы в своем предположении, что Firebug не содержит специальных оболочек для форматирования объектов jQuery. Быстрый поиск показывает соответствующее сообщение в списке рассылки Firebug. Предполагая, что информация по-прежнему правильная (сообщение с января) Firebug будет отформатировать объект как массив, если он имеет конечную длину и splice метод.. p >

JQuery выполняет оба этих критерия, но их реализация splice - не что иное, как прямая копия собственного метода Array, Он недокументирован, что означает его либо только для внутреннего использования, либо, возможно, только для цели использования Firebug в форматировании объектов jQuery.

Ответ 2

Посмотрите код 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;
},

Это связано с тем, что любой результат jquery-запросов - это массив.