Как стать автором
Обновить

Комментарии 37

Отдельное спасибо за «jQuery.fx.interval»
Всегда пожалуйста)
Пункты 5 и 6, вроде как, описаны в документации. Правда на деле ни разу не приходилось передавать туда функцию.

Пункт 7 — это обычный селектор CSS, как бы он по логике и должен быть в jQuery.

Насчёт пункта 12…
Вроде как атрибут disabled=«disabled» не всегда игнорировался.
Насколько я помню, мне как раз и приходилось писать костыли, чтобы при клике на ссылку или DIV проверять, есть ли disabled или нет.
Проще говоря, событие всё же вызывалось.

Пункты 17 и 18 тоже описаны в документации.

— >>и хотя я считаю себя продвинутым JavaScript разработчиком
Хороший такой специалист :)

>> не читал исходники jQuery с начала и до конца
К слову, я тоже не читал.
Уверен, что прочитав мануал на сайте jQuery, можно ещё больше узнать интересных вещей и поведений.

P.S.:
А так…
Когда-то давно прочитал в одной из статей о jQuery, зачем в функцию вставляется аргумент с названием undefined.
И теперь всегда использую обрамление скриптов следующим кодом: (function(window, document, undefined){}(document, jQuery)),
Когда-то давно прочитал в одной из статей о jQuery, зачем в функцию вставляется аргумент с названием undefined.

Потому что undefined, который на самом деле переменная window.undefined, может быть перекрыт. А в вашем примере self-invoking function, код внутри начинает использовать undefined параметр, переданный в функцию, который неожиданно без инициализации имеет значение примитивного типа undefined.
undefined передают как переменную внутрь просто ради профита от ее переименования в более короткий вариант в процессе сжатия исходников :}
тоже верно, хотя сам предпочитаю не передавать, не так уж часто undefined используется в чистом виде
(function(undefined){console.log(undefined);})(17)
Ничего себе!
Неправда. undefined объявляют аргументом именно за тем, чтобы получить «настоящую» неопределенную переменную.
попробуйте переопределить undefined в браузерах, которые поддерживает jquery 2, а потом посмотрите что

(function() { console.log(undefined); })();
после минификации останется таким же

а вот
(function(undefined) { console.log(undefined); })();
станет каким-нибудь вот таким:
(function(a) { console.log(a); })();

профит очевиден, а за размером в jquery следят ололо как
Эта техника использовалась в библиотеках за долго до jQuery2. Бонус после минификации — всего лишь сторонний эффект.
да, видимо так и есть, спасибо
и тут я открыл исходники jquery 2 и увидел что там больше так не делают.
видимо, я и правда был не прав и минификация — лишь побочный плюс :{
«In modern browsers (JavaScript 1.8.5 / Firefox 4+), undefined is a non-configurable, non-writable property per the ECMAScript 5 specification» (тут).
По поводу :empty.
В CSS :empty срабатывает только если в теге нет ни вложенных тегов, ни символов. Даже <td>& nbsp;</td> не подцепится через :empty
ну так какой же это empty?

Вот то, что он пробельные символы(незначащие для HTML) не опознаёт как empty — нехорошо:
   $('<ul>\n</ul>').is(':empty');
false
   $('<ul></ul>').is(':empty');
true
Всё ок, вот описание соответствующего псевдокласса на MDN:

The :empty pseudo-class represents any element that has no children at all. Only element nodes and text (including whitespace) are considered. Comments or processing instructions do not affect whether an element is considered empty or not.

+ демо: codepen.io/anon/pen/LcJtC
В селекирах CSS 4-го уровня описывается псевдо-класс :blank, который будет ловить элементы с пробельными символами — dev.w3.org/csswg/selectors4/#the-blank-pseudo.
Обрамление скриптов позабааило))) А так, ну да одна из реализаций области видимости с помощью самовызывающейся функции, только вопрос зачем вы переопределили window как document, а document как jQuery? Либо вы не понимаете что написали, либо я не понимаю зачем вам это.
$.grep: Этот метод похож на Underscore метод _.filter, он также принимает два аргумента, массив элементов и функцию, и возвращает элементы, которые прошли тест функции.
Для полноты картины уместно упомянуть (и упоминаю), что оба они служат костылями для браузеров, не имеющих поддержки метода Array.prototype.filter то есть, честно говоря, только для Internet Explorer восьмой версии и более ранних версий его.

Проще программировать с использованием этого метода, а старые IE подпирать посредством «es5-shim» с сохранением синтаксиса.
Сразу уточню, что здесь «честно говоря» означает «честно оценивая современную ситуацию». (Строго-то говоря, у Firefox 1.5 также не было поддержки Array.prototype.filter но эта версия Файерфокса вымерла, тогда как IE8 преспокойно продолжает крутиться в Windows XP.)
Справедливости ради надо сказать, что _.filter() работает с любыми коллекциями (а не только с массивами), и временами это весьма удобно.
Array.from(коллекция).filter(…)
Не работает для объектов:

var collection = {
        foo: 'bar',
        baz: 'qux'
};

var predicate = function (x) {
        return x === 'bar';
};

console.log(Array.from(collection).filter(predicate)); // []
console.log(_.filter(collection, predicate)); // [ 'bar' ]
console.log(Array.prototype.filter.call(collection, predicate));
Можно Array.prototype.filter.call для array-like объектов использовать:

var arrayLikeObj = {
  0: 42,
  1: 'foo',
  2: 101,
  3: 300,
  4: 'bar',
  5: 'baz',
  6: Infinity,
  7: 'qux',
  length: 8
};

console.log(Array.prototype.filter.call(
  arrayLikeObj,
  function(item) {
    return typeof item == 'number';
  }
));
// [42, 101, 300, Infinity] 
см. коммент выше: не работает для объектов
Я написал что для array-like объектов, т.е. для объектов с полями-индексами и length. Или arguments, например :)
Для обычных объектов, разумеется, нет. Хотя для примера из вашего комментария можно соорудить что-то вроде этого:

var collection = {
  foo: 'bar',
  baz: 'qux'
};

var predicate = function (x) {
  return collection[x] === 'bar';
};

console.log(Array.prototype.filter.call(Object.keys(collection), predicate).map(function(key) { return collection[key]; }));


Но это уже легкий изврат :)
Я в таких случаях предпочитаю писать более прямой и понятный код. По крайней мере поведение _.filter в данном случае мне кажется не совсем очевидным, поскольку фильтрующая функция применяется к значениям, а не к ключам объекта или хотя бы к парам [ключ, значение]. Но это ИМХО, конечно.
Нет, я знаю, как работает Array.prototype.filter(), и так же знаю, как работает _.filter(), и просто напоминаю про разницу (чтоб не сложилось по первому комменту мнения, что это идентичные функции.
Стоит отметить, что часть описанного выше есть в документации, как верно отметил zalatov_a, недокументированные же функции очень не рекомендуются к использованию авторами jquery, т.к. если их не задокументировали, то скорее всего были причины и авторы jQuery оставляют за собой возможность делать в них изменения без каких-бы то ни было предупржлений и уведомлений, что может подарить вам прекрасные ночи в обнимку с дебаггером.

Поэтому читать про такие фишки — интересно, знать — полезно, использовать — на свой страх и риск.
Мы обычно передаем строку с именами классов в функцию $.fn.addClass. Но она также принимает функцию. Переданная функция должна возвращать строку с именами классов разделенными пробелом.


Эээ… и что тут «удивительного»? Для JS это очень нормально — помещать функции в аргументы — лишь бы возвращали ожидаемое.
В 13м пункте можно еще и делегирование событий делать

$(".parent").on({
    click: function() {
        $( this ).toggleClass( "active" );
    }, mouseenter: function() {
        $( this ).addClass( "inside" );
    }, mouseleave: function() {
        $( this ).removeClass( "inside" );
    }
}, '.children'); // <- от тут
Жаль не $(".parent").on(".children", {...}); хотя, там и так аргументами жонглируют как сумасшедшие…
Что первый вариант, что второй вариант мне кажется… странным… и не совсем понятным.

Наверно, всё дело в том, что примеры неправильные.
Надо не с CSS-селекторами оперировать, а с переменными или объектами типа document, window.

Ведь, общепринято использовать $('.parent .child').on(...);

А вот если $(document).on($link, ...), тогда да…
$link в данном случае все-равно должен быть селектором, а на document, по возможности, лучше не вешать.

Но дело в другом, если перечень событий и колбеков большой, можно запутаться, хотя js разработчики давно привыкли читать с начала и с конца, а потом посередине (:
можно запутаться

Чтобы не путаться извращенцы типа меня пишут код немного иначе:

var onclick = function(){ $(this).toggleClass("active");}
var onenter = function(){ $(this).addClass("inside");}
var onleave = function(){ $(this).removeClass("inside");}
var binds = {
  click: onclick,
  mouseenter: onenter,
  mouseleave: onleave
};
$(".parent").on(binds, '.children');

При небольшом списке "binds" может быть лишним, но функции в аргументе-объекте — это ад для читателя.

В таком примере все еще хуже, если код будет длинный или навешиваться будет на несколько различных элеметов — разбор доступных переменных займет лишнее время, такой код сложно поддерживать.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации