Встроить прототипные функции, такие как Array.map, Array.filter ПРОТИВ _.map, _.filter

#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(...);
});