Примечание: В конце статьи есть QR-код личного публичного аккаунта, и будут опубликованы другие технические статьи, так что следите за обновлениями.
В этой статье объясняетсяФункции высшего порядкаЭто продолжение описанных ранее замыканий, поэтому, прежде чем изучать функции более высокого порядка, убедитесь, что вы понимаете понятия замыканий и области видимости:
понимать абстракцию
выявлять абстрактные понятия
Студенты с опытом разработки на Java, C# и т. д. не должны быть незнакомы с идеей абстракции кода.Абстрактных классов и интерфейсов обычно пишут много, но для студентов, которые всегда занимались фронтенд-разработкой, слово «абстрактный» относительно незнаком, в конце концов, в JavaScript нет абстрактного интерфейса.
Но идея абстракции кода в JS определенно есть, но форма отличается от таких языков, как Java!
Давайте сначала посмотрим на абстрактный класс в Java:
public abstract class SuperClass {
public abstract void doSomething();
}
Это класс на Java.В классе есть абстрактный метод doSomething.Теперь я не знаю, что делает метод doSomething в подклассе, поэтому я определяю этот метод как абстрактный метод, и пусть подкласс реализует конкретную логику сам по себе.
Создайте подкласс для реализации SuperClass:
public class SubClass extends SuperClass{
public void doSomething() {
System.out.println("say hello");
}
}
doSomething в подклассе выводит строку «скажи привет», а другие подклассы будут иметь другие реализации, которые являются абстрактными классами и реализациями в Java.
Итак, что такое абстракция в JS, самая классическая — функция обратного вызова:
function createDiv(callback) {
let div = document.createElement('div');
document.body.appendChild(div);
if (typeof callback === 'function') {
callback(div);
}
}
createDiv(function (div) {
div.style.color = 'red';
})
В данном примере есть функция createDiv, которая отвечает за создание div и добавление его на страницу, но как дальше работать с этим div, функция createDiv не знает, поэтому даем разрешение тому, кто вызвал createDiv function, let Вызывающий определяет следующую операцию, и div передается вызывающему в виде обратного вызова.
Это также отражает абстракцию.Поскольку вы не знаете следующую операцию div, вы можете напрямую передать ее вызывающей стороне и позволить вызывающей стороне реализовать ее. Идея абстрактных методов в абстрактных классах в Java такая же.
Резюмируя абстрактные понятия:Абстракция заключается в том, чтобы скрыть более конкретные детали реализации и посмотреть на проблему, которую мы хотим решить, с более высокого уровня..
Абстракция обхода в массивах
При программировании не все функции готовые.Например в приведенном примере может быть создано несколько div и обработка каждого div может быть разной.Необходимо абстрагировать неизвестные операции и зарезервировать вход для операций.Как программисты, мы должны иметь такое мышление абстрагирования кода, когда это уместно.
Далее, давайте рассмотрим несколько методов работы с массивами, представленных в ES5, и вы сможете глубже понять абстрактную идею Способ обхода массива до ES5:
var arr = [1, 2, 3, 4, 5];
for (var i = 0; i < arr.length; i++) {
var item = arr[i];
console.log(item);
}
Присмотритесь.В этом коде используется for, а затем значения берутся по порядку.Вы чувствуете, что эта операция недостаточно элегантна, оставляя скрытые опасности для ошибок, таких как неправильное написание длины и случайное повторное использование я. В этом случае мы можем извлечь функцию? Самый важный момент, все, что мы хотим, это каждое значение в массиве, а затем манипулировать этим значением, тогда мы можем скрыть процесс обхода:
function forEach(arr, callback) {
for (var i = 0; i < arr.length; i++) {
var item = arr[i];
callback(item);
}
}
forEach(arr, function (item) {
console.log(item);
});
Приведенный выше метод forEach скрывает детали обхода, возвращает элемент, с которым хочет работать пользователь, и возвращает i и сам arr в обратном вызове:callback(item, i, arr)
.
Метод forEach, изначально предоставляемый JS, выглядит следующим образом:
arr.forEach(function (item) {
console.log(item);
});
К методам того же семейства, что и forEach, относятся также map, some, every и т. д. Идея та же, эта абстракция может сделать удобнее пользователям, а коллегам сделать код понятнее.
Абстракция — важная идея, позволяющая сделать код более элегантным и простым в использовании.Абстрактные идеи также используются в функциях более высокого порядка, поэтому, чтобы изучить функции более высокого порядка, вы должны сначала понять абстрактные идеи..
Функции высшего порядка
Что такое функция высшего порядка
Функция, удовлетворяющая хотя бы одному из следующих условий, является функцией высшего порядка:
-
Передайте другие функции в качестве аргументов
-
возвращаемая функция как возвращаемое значение
Проще говоря, этоФункция может работать с другими функциями, принимая другие функции в качестве аргументов или возвращая функции в качестве возвращаемых значений. Я считаю, что студенты, которые писали код JS, могут легко понять эту концепцию, потому что в JS функция — это обычное значение, которое можно передать и вернуть.
Параметры могут быть переданы и возвращены, Студентам, которые разрабатывают такие языки, как Java, может быть немного сложно понять, потому что язык Java не такой гибкий, но, вероятно, это то, что означает лямбда Java8;
функция передана как параметр
В качестве параметра передается функция обратного вызова, упомянутая выше. Функция обратного вызова часто используется в асинхронных запросах. Пользователь хочет использовать данные, возвращенные из запроса, для выполнения некоторых операций после успешного запроса, но он не знает когда запрос закончится.
Используйте jQuery, чтобы сделать запрос Ajax:
function getDetailData(id, callback) {
$.ajax('http://xxxxyyy.com/getDetailData?' + id, function (res) {
if (typeof callback === 'function') {
callback(res);
}
});
}
getDetailData('78667', function (res) {
// do some thing
});
Такие операции, как Ajax, очень подходят для использования обратных вызовов.Когда функция не подходит для выполнения каких-то определенных операций или когда вы не знаете, как работать, вы можете передать соответствующие данные другой функции, и пусть другая функция их выполнит. , и эта функция является переданной функцией обратного вызова.
Еще один типичный примерсортировка массива.
функция возвращает значение
При оценке типов данных чаще всего используется typeof, но typeof имеет определенные ограничения, такие как:
console.log(typeof []); // 输出object
console.log(typeof {}); // 输出object
Судя по тому, что и массивы, и объекты являются выходными объектами, если вы хотите более подробное суждение, вы должны использовать Object.prototype.toString
console.log(Object.prototype.toString.call([])); // 输出[object Array]
console.log(Object.prototype.toString.call({})); // 输出[object Object]
На основе этого мы можем написать методы для оценки объектов, массивов и чисел:
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
function isArray(arr) {
return Object.prototype.toString.call(arr) === '[object Array]';
}
function isNumber(number) {
return Object.prototype.toString.call(number) === '[object Number]';
}
Мы обнаружили, что эти три метода слишком похожи, чтобы выполнять некоторую экстракцию:
function isType(type) {
return function (obj) {
return Object.prototype.toString.call(obj) === '[object ' + type + ']';
}
}
var isArray = isType('Array');
console.log(isArray([1,2]));
Этот метод isType является функцией более высокого порядка, которая возвращает функцию и использует замыкания, чтобы сделать код элегантным.
Применение функций высшего порядка
использование в лодаше
Функции высшего порядка часто используются в обычной разработке, но иногда вы не знаете, что используете функции высшего порядка, и они также часто используются в некоторых библиотеках классов с открытым исходным кодом, таких как известныеlodash, выберите одну из предыдущих функций:
function before(n, func) {
let result
if (typeof func != 'function') {
throw new TypeError('Expected a function')
}
return function(...args) {
if (--n > 0) {
result = func.apply(this, args)
}
if (n <= 1) {
func = undefined
}
return result
}
}
В функции before полезно такжепередать функцию как,опять такивозвращает функцию, что является классическим примером функции высшего порядка.
Посмотрите, как можно использовать этот код:
jQuery(element).on('click', before(5, addContactToList))
Таким образом, функция before должна вызывать метод не более n раз.
Примечание: код функции before не сложен, и его несложно использовать, но знания, которые необходимо понять для такого простого инструментального метода, следующие: область действия, замыкание и функции более высокого порядка, поэтому когерентны, и тогда нам нужно написать оСерия шаблонов проектирования JavaScript, также используйте эти знания.
регулирование функции
При написании кода в большинстве случаев мы вызываем функции по собственной инициативе. Однако в некоторых случаях вызов функции не контролируется пользователем напрямую, и в этом случае функция может быть отключена от частых вызовов, вызывая проблемы с производительностью.
существуетElement-UI, существует компонент el-autocomplete, который может отображать связанные элементы ввода под полем ввода, когда пользователь печатает:
На самом деле, когда пользователь вводит, он может использовать введенный контент для поиска.Ele.me использует компонент ввода при реализации этого компонента и отслеживает ввод пользователя:
Если событие ввода используется для отслеживания пользовательского ввода, каждое слово, введенное пользователем, будет запускать этот метод. Если входное содержимое должно использоваться для веб-поиска, и каждое слово, введенное пользователем, ищется, частота срабатывания слишком высока. , и производительность Потребление немного велико, и пользовательский опыт не очень хорош, когда сеть относительно плохая.
Ele.me также учла эти проблемы при реализации этого компонента, используя более распространенную практику в отрасли→дросселирование, то есть после ввода отложить поиск на некоторое время и игнорировать следующий поисковый запрос, если отложенное выполнение не было завершено.
Взгляните на его реализацию:
Идея регулирования автозаполнения — это только что упомянутая, и она используетthrottle-debounceРеализация этой библиотеки инструментов является использование функций высшего порядка. Заинтересованные студенты могут увидеть свой исходный код: https://github.com/niksy/throottle-debounce, код не сложен.
Существуют и другие способы использования функций высшего порядка, например, в шаблонах проектирования, которые будут подробно описаны позже.
обращать внимание
Вы можете обратить внимание на мой паблик: icemanFE и продолжать обновлять технические статьи!