Разбор Underscore
(function () { }.call (this)); // моментальное выполнение, this внутри как снаружи
if (!(this instanceof _)) return new _(obj); // когда надо, чтобы функция что-то конструировала
var createCallback = function (func, context, argCount) { return function (value) { // когда надо создать другую, внутри которой будет работать наша return func.call (context, value); }; };
_.each = _.forEach = function (obj, iteratee, context) {}; // создание функции и крепление ее на _
_.find = _.detect = function (obj, predicate, context) { predicate = _.iteratee (predicate, context); // подмена пришедшего predicate на созданную из него функцию _.some (); // вызов одной, навешенной на черточку функции, внутри другой };
_.some (obj, function (value, index, list) { }); // создание и передача одной функции как аргумент в другую
// создает функцию, var group = function (behavior) { // часть поведения которой передается в аргументах return function (obj, iteratee, context) { // то есть, созданные функции работают одинаково behavior (result, value, key); // только под конец — по разному return result; }; }; _.indexBy = group (function (result, value, key) { // сама генерация result[key] = value; });
// кусок кода, который выполняет часть себя, потом, если надо, запускает свою копию, ждет пока копия выполнится, потом выполняет оставшуюся часть себя var flatten = function (input, shallow, strict, output) { for (var i = 0, length = input.length; i < length; i++) { flatten(value, shallow, strict, output); // подныривает во встреченные вложенные массивы } };
// обертывание одной функции вокруг другой _.flatten = function (array, shallow) { return flatten (array, shallow, false, []); };
// аналог var x = func.bind (obj), означает, что каждый раз, когда делается так: x (), // происходить будет что-то типа obj.func (), то есть this внутри func будет obj nativeBind.apply (func, slice.call (arguments, 1))
// подмена методов объекта на их обертки, которые всегда вызывают оригиналы на этом объекте // то есть нельзя будет вызвать метод объекта и передать ему в качестве this посторонний объект obj[key] = _.bind (obj[key], obj);
// создание функции со своим _.memoize = function (func, hasher) { var memoize = function (key) {}; memoize.cache = {}; // личным объектом для запоминания return memoize; };
// задержка выполнения функции setTimeout (function (){ return func.apply (null, args); }, wait);
// функция, которая из названия делает другую функцию _.property = function (key) { return function (obj) { return obj[key]; // которая выдергивает из переданного объекта значение названного свойства }; };
// закидывает функцию _.prototype[name] = function () { // с именем name в прототип черточки var args = [this._wrapped]; push.apply (args, arguments); return result.call (this, func.apply (_, args)); }; // после чего будет работать вот это: var x = new _; x[name]();