#javascript #underscore.js #each #wrapper
#javascript #underscore.js #каждый #оболочка
Вопрос:
Я читал аннотированный источник для Underscore.js и мне было интересно, как он используется this._wrapped
при передаче объекта _()
функции в отличие от обычного способа передачи объекта функции _
объекта.
Это:
_(myObj).each(callback);
Против:
_.each(myObj, callback);
Когда я запускаю первый вызов функции и приостанавливаю его в инструментах разработчика, в конечном итоге код заканчивается здесь:
_.mixin = function(obj) {
_.each(_.functions(obj), function(name) {
var func = _[name] = obj[name];
_.prototype[name] = function() {
var args = [this._wrapped];
push.apply(args, arguments);
return result(this, func.apply(_, args));
};
});
};
Но я не уверен, как он узнал, что нужно туда идти. Может ли кто-нибудь помочь мне понять это? Кроме того, я пытался искать ответ раньше, но этот конкретный вопрос, похоже, никогда не возникал. Если на этот вопрос уже был дан ответ, приношу свои извинения.
Ответ №1:
Использование подчеркивания в объектно-ориентированном стиле:
_([1, 2, 3]).map(function(n){ return n * 2; });
Вызывает создание экземпляра объекта:
var _ = function(obj) {
if (obj instanceof _) return obj;
if (!(this instanceof _)) return new _(obj); // on this line
this._wrapped = obj;
};
Волшебство, которое можно легко пропустить, заключается в отсутствии new
ключевого слова, функция вызывается как любая другая функция (не как конструктор), this
будет ссылаться на родительскую область (а не быть экземпляром _
), поэтому запускает new
оператор (и конструкцию объекта). Это очень умный способ избежать принудительного использования new
.
Смотрите https://jsfiddle.net/336493L6 / чтобы увидеть этот паттерн в действии.
Все функции, статически используемые для объекта подчеркивания (each, map и т. Д.), Применяются к прототипу подчеркивания с помощью _.mixin
функции.
Это строка, в которой это происходит:
_.mixin(_);
Конечно, при отладке вы окажетесь в mixin
функции, поскольку она оборачивает статические функции.
_.prototype[name] = function() {
var args = [this._wrapped];
push.apply(args, arguments);
return result(this, func.apply(_, args));
};
Эта прототипная версия статической функции вызовет статическую функцию с первым параметром, установленным this._wrapped
равным . result
в этом случае возвращаемое значение функции не изменится (оно используется для _.chain
).
Комментарии:
1. @Tomalak — вы неправильно прочитали, вторая строка проверяет
!(this instanceof _)
, что будет иметь место, если_()
вызывается безnew
, однако, когда это выполняется, оно, в свою очередь, вызоветnew _(obj)
, который завершится ошибкой как первого, так и второго оператора if и достигнет 3-й строки.2. Я обновил ответ с помощью JSFiddle, показывающего шаблон, о котором я говорю