#javascript #underscore.js
#javascript #underscore.js
Вопрос:
Может кто-нибудь объяснить мне, в чем разница между прототипной функцией массива, такой как map,filter, reduce, и функцией подчеркивания .map,.fiter,_.reduce.
мы можем решить проблему, используя array.map, array.filter и array.reduce. однако почему в основном используется функция подчеркивания?
Пожалуйста, предложите любую ссылку или сообщите мне доказательство концепции.
Спасибо,
Ответ №1:
Как правило, функции подчеркивания работают со списками (объектами, которые некоторым образом можно рассматривать как массивы), в то время как прототипы работают только с объектом, к которому они прикреплены. Например, _.map()
работает с объектами (словарями), в то время как Array.prototype.map()
вызывается только из массивов.
Комментарии:
1. Что ж, хороший улов. Я, честно говоря, действительно не заметил, что вызов мышечной памяти
_.map()
никогда не замечалsomeObject.map
, это не вещь.
Ответ №2:
Я думаю, @ouroborus отвечает на ваш главный вопрос, массивы и объекты разные, а подчеркивания map, forEach и reduce предназначены для использования с объектами (не массивами)
Некоторые из функций, о которых вы упоминали до недавнего времени, просто не входили в ядро ECMAScript / JavaScript даже для массивов. Библиотеки были созданы программистами, которым надоело создавать свои собственные снова и снова. Но они также не хотели возиться с прототипными изменениями основных объектов, с которыми они работали. Не вдаваясь в подробности каждой функции, в документации Mozilla указано, в какой редакции ECMAScript была добавлена функция.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
Одно замечание. некоторые фреймворки, такие как angular, например, также повторно реализуют такие вещи, как .forEach
, однако в некоторых из этих случаев требуется пользовательская реализация, например, в случае с angular.forEach
, где он пропускает свойства, начинающиеся с $
.
Комментарии:
1. … предназначены для использования с объектами (не массивами) — это неверно, подчеркивание
map
/filter
/reduce
работает для объектов и массивов. Кроме того, хотя ваша ссылка полезна, она зависит от браузера и может содержать больше изменений, чем ES5, вот еще одно: kangax.github.io/compat-table/es5
Ответ №3:
Глядя на filter
, map
и reduce
.
Все следующее приведет к тому же результату:
_.filter([1,2,3], function(n) { return n % 2 });
[1,2,3].filter(function(n) { return n % 2 });
// [1,3]
_.map([1,2,3], function(n) { return n * 10; });
[1,2,3].map(function(n) { return n * 10; });
// [10,20,30]
_.reduce([1,2,3], function(a,b) { return Math.max(a,b); });
[1,2,3].reduce(function(a,b) { return Math.max(a,b); });
// 3
Если смотреть конкретно на map
и параметры, переданные итератору, они одинаковы:
_.map([1,2,3], function(el, index, array) { ... })
[1,2,3].map(function(el, index, array) { ... })
Однако, как уже упоминалось в других постерах, методы подчеркивания также работают с объектами, но помимо этого они также работают с массивоподобными объектами, из http://underscorejs.org/#each:
Примечание: Функции сбора данных работают с массивами, объектами и массивоподобными объектами, такими как аргументы, список узлов и подобными.
Также упоминается в других постерах, что любой браузер, не поддерживающий ES5 (выпущен в апреле 2009), не будет предоставлять эти реализации по умолчанию. http://kangax.github.io/compat-table/es5
Но наконец, есть функция подчеркивания, не доступные в стандартных реализаций, это возможность установить связи в итераторе:
var obj = {A: true, B: false, C: true};
_.map(['B','B','C'], function(key) { return this[key]; }, obj);
// [false,false,true]
Почему это может быть полезно? Не удалось obj
получить доступ к функции? Да, это возможно. Обычный вариант использования для передачи контекста таков:
_.map([...], function(item) {
this.parentScopeFunction(...);
}, this);
Чтобы сделать это с реализациями по умолчанию, шаблон более подробный:
var parentScope = this;
[...].map(function(item) {
parentScope.parentScopeFunction(...);
});