Ответ 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()
-используть их. Таким образом, вы можете увидеть весь графический объект, все его свойства и т.д.