карта () получить () путаница - PullRequest
22 голосов
/ 25 января 2011

Я просто прохожу через jQuery API и немного запутался в методе 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() делают в этом фрагменте кода?

Заранее спасибо.

Ответы [ 3 ]

54 голосов
/ 25 января 2011

Основы

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

  1. Перебрать объект jQuery (коллекцию, что угодно), для которого была вызвана функция. В данном случае это $(this), то есть независимо от того, на что была вызвана функция .equalizeHeights() ... $('div'): все элементы <div> на странице (фух).
  2. Создать массив с тем же количеством элементов, что и у объекта, к которому был вызван .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's just an array.
console.log($.isArray(two.get()));    // true

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

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

5 голосов
/ 25 января 2011

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

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

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

3 голосов
/ 25 января 2011

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

Get возвращает массив чистых элементов, которые были обернуты в объекты jquery, как заметил один день.(Исправлено)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...