Map() get() путаница

Я просто просматриваю API jQuery, и я немного запутался в методах map() и get(). Я знаю, что ошибаюсь, но метод map() очень похож на инструкцию .each()? Кроме того, в документации говорится, что он возвращает новый объект jQuery.

Я играл с этим на jsfiddle, пытаясь обнять его, но я не совсем там. здесь является ссылкой jsfiddle:

Также приведен фрагмент кода:

$.fn.equalizeHeights = function() {
    var two = $(this).map(function(i, e) {
                                return $(e).height();
                            });
    console.log(two);
    console.log(two.constructor);
    console.log(two.get());
    console.log(two.get().constructor);
    return this.height(Math.max.apply(this,two.get()));
}
$('input').click(function() {
    $('div').equalizeHeights();
});

Я вижу, что они расширяют jQuery, используя прототип, чтобы создать функцию под названием equalizeHeights(). И $(this) представляет селектор для всех элементов "div" на странице. Вызов map() выполняет итерацию через каждый из элементов массива div и возвращает его высоту? Но то, о чем я смущаюсь, это то, что я вхожу на консоль. Один из них - object, а другой - array?

Может ли кто-нибудь уточнить, что делают map() и get() в этом фрагменте кода?

Спасибо заранее.

Ответ 1

Основы

Существуют две различные функции jQuery map(): .map() и $.map(). Они выполняют подобные вещи, но по разным коллекциям. Вы используете первую форму, которая выполняет следующие действия:

  • Итерация над объектом jQuery (коллекция, что угодно), на котором была вызвана функция. В этом случае это $(this), которое было вызвано функцией .equalizeHeights() на..., которая представляет собой $('div'): все <div> элементы на странице (phew).
  • Создайте массив с тем же количеством элементов, что и объект, на который был вызван .map() (все div на странице, помните), чей элемент n th генерируется путем вызова при условии обратного вызова - я доберусь туда через секцию n th в целевом объекте jQuery. В этом конкретном случае этот обратный вызов является этой функцией:

    function(i, e) { return $(e).height(); }

Да, .map() выглядит как .each(), но есть ключевое различие:

  • .each() выполняет действие над каждым элементом в коллекции; возвращаемое значение обратного вызова, переданного в .each(), используется для определения того, продолжается или нет итерация.
  • .map() также выполняет действие для каждого из элементов в коллекции, но возвращаемое значение обратного вызова используется для генерации элемента в подобном массиву объекте, возвращаемом .map().

Вы все еще со мной?

Объекты jQuery похожи на массивы, но они не являются массивами! Причина, по которой вы вызываете .get() в конце вызова .map(), состоит в том, чтобы превратить этот объект jQuery в истинный массив. Элементами этого массива являются значения, возвращаемые обратным вызовом.

Объединяя все это

Эта функция устанавливает высоту каждого <div> на странице на высоту самого высокого <div>. Вот как:

$('input').click(function() {   // bind a click listener to every <input> element
    $('div').equalizeHeights(); // ...that will call the equalizeHeights() fn
                                //    on all <div> elements when fired
});

Итак, посмотрев определение equalizeHeights():

$.fn.equalizeHeights = function() {
    // construct an array that contains the height of every <div> element
    var two = $(this).map(function(i, e) {
                                return $(e).height();
                          });


    return this.height(    // set the height of element <div> element to...
        Math.max.apply(    // the largest value in...
            this,two.get() // the array of height values
        )
    ); // ...and finally, return the original jQuery object to enable chaining
}

Но как насчет бизнеса constructor?

Как вы обнаружили, да, один объект (объект jQuery), а другой - массив. Для этого вам понадобится вызов .get(), чтобы превратить объект, подобный массиву, в нечто, что Math.max() может понять.

Вместо того, чтобы смотреть на свойство constructor, вы можете использовать немного больше jQuery, чтобы выяснить, что именно вы смотрите:

console.log(two.jquery);         // the version of jquery, something like "1.4.4"
console.log($.isArray(two));     // is it a plain old JS array? false
console.log(two.get().jquery);   // undefined! it just an array.
console.log($.isArray(two.get()));    // true

Еще лучше посмотреть фактические объекты внутри отладчика, а не просто console.log() -используть их. Таким образом, вы можете увидеть весь графический объект, все его свойства и т.д.

Есть вопросы? Комментарий прочь.

Ответ 2

map проходит через объект jQuery и применяет функцию к каждому элементу. Возвращаемое значение каждого вызова добавляется в массив. Затем этот массив переносится в объект jQuery и возвращается.

get возвращает массив, содержащий каждый элемент в объекте jQuery. Это означает, что он по существу разворачивает выбор, возвращаемый map, и получает простой массив JS.

В вашем примере map создает выбор, содержащий высоту каждого элемента. Затем вы вызываете get на нем так, чтобы нативная функция JS Math.max могла его понять. this.height() затем устанавливает высоту каждого элемента в выборе наибольшего значения в массиве.

Ответ 3

Each, похоже, не возвращает результирующий массив, пока map возвращает массив, содержащий значения возврата для всех обратных вызовов.

Get возвращает массив чистых элементов, которые были обернуты в объекты jquery, как указано в lonesomeday. (Скорректированный)