предисловие
предыдущий пост«Принцип и использование этой «Серии вопросов для предварительного интервью 4»В , звоните и обращайтесь.
Их главная роль состоит в том, чтобы изменить точку этого. В обычной работе, в дополнение к некоторым базовым методам написания классов или общедоступных библиотек, когда они будут использоваться, другие случаи вызова и применения сценариев приложений не так много.
Однако, когда вы сталкиваетесь с ним внезапно, вам нужно подумать об этом, прежде чем вы сможете обернуться. Итак, сегодня давайте внимательно рассмотрим различия между этими двумя методами и некоторыми магическими применениями. Наконец, будет представлен метод связывания, аналогичный его использованию.
Что общего у call и apply
Их объединяет то, что они могутИзменить контекст, в котором выполняется функция, метод одного объекта передается другому объекту для выполнения, и он выполняется немедленно.
Зачем менять контекст выполнения? Приведу небольшой пример из жизни: в обычное время мне некогда готовить, а на выходные хочу приготовить рассол для своих детей. Но подходящей сковороды нет, а идти и покупать не хочется. Поэтому я попросил соседа одолжить горшок для использования, что не только достигло цели, но и сэкономило деньги, убив двух зайцев одним выстрелом.
То же самое верно и для изменения контекста выполнения.Объект А имеет метод, и объект Б также должен использовать тот же метод по какой-то причине.На данный момент мы должны расширить метод только для объекта Б или позаимствовать метод объекта А? Шерстяная ткань? Конечно, объект A заимствован, что не только соответствует требованиям, но и снижает использование памяти.
Кроме того, они пишутся одинаково,Объект, для которого вызываются call и apply, должен быть функцией.. Далее речь пойдет о конкретном способе написания, который и является основным проявлением их различия.
Разница между вызовом и применением
Разница между ними в основном отражается в способе записи параметров. Давайте сначала посмотрим на их конкретное письмо.
Как написать звонок
Function.call(obj,[param1[,param2[,…[,paramN]]]])
Необходимо отметить следующие моменты:
- Объект для вызова call должен быть функцией.
- Первым параметром вызова является объект. Вызывающий функцию укажет на этот объект. Если не передано, по умолчанию используется окно глобального объекта.
- Начиная со второго параметра, он может принимать любое количество параметров. Каждый параметр сопоставляется с параметром функции в соответствующей позиции. Но если все параметры будут переданы в виде массива, они будут сопоставлены с первым параметром, соответствующим функции в целом, и тогда параметры будут пустыми.
function func (a,b,c) {}
func.call(obj, 1,2,3)
// func 接收到的参数实际上是 1,2,3
func.call(obj, [1,2,3])
// func 接收到的参数实际上是 [1,2,3],undefined,undefined
Как написать заявку
Function.apply(obj[,argArray])
нужно знать, это:
- Его вызывающей стороной должна быть функция Function, и она принимает только два параметра.Правила для первого параметра такие же, как и для вызова.
- Второй параметр, который должен быть массивом или подобным массиву, будет преобразован в массивы, подобные массиву, переданы в функцию и сопоставлены с соответствующими параметрами функции. Это также важное различие между вызовом и применением.
func.apply(obj, [1,2,3])
// func 接收到的参数实际上是 1,2,3
func.apply(obj, {
0: 1,
1: 2,
2: 3,
length: 3
})
// func 接收到的参数实际上是 1,2,3
Что такое массив классов?
Давайте сначала поговорим о массивах, с которыми мы все знакомы. Его характеристики таковы: его можно вызывать через индекс, такой как array[0]; он имеет атрибут длины length; его можно пройти через цикл for или метод forEach.
Итак, что такое массив классов? Как следует из названия, этоОбъекты с характеристиками массива. Например, следующий объект представляет собой массив классов.
let arrayLike = {
0: 1,
1: 2,
2: 3,
length: 3
};
Подобный массиву arrayLike можно вызывать через индекс, он имеет атрибут длины, а также может проходить через цикл for.
Array-like по-прежнему используется чаще, но обычно мы можем этого не замечать. Например, наш метод получения узла DOM возвращает массив классов. В другом примере все параметры, полученные с использованием аргументов в методе, также являются массивом класса.
Но следует отметить, что:Подобный массиву нельзя использовать методы в цепочке прототипов массива, такие как forEach, splice, push и т. д., в конце концов, это не массив.
Цель звонка и заявки
Некоторые сценарии использования вызова и применения перечислены ниже. Отказ от ответственности: в примере нет сцены, где нужно использовать call или apply, это просто личная привычка.
сценарии использования звонков
1. Наследование объектов. Например, следующий пример:
function superClass () {
this.a = 1;
this.print = function () {
console.log(this.a);
}
}
function subClass () {
superClass.call(this);
this.print();
}
subClass();
// 1
Подкласс наследует метод печати и переменную суперкласса через метод вызова. Кроме того, подкласс также может расширять свои собственные методы.
2. Метод заимствования. Помните массив классов только что? Если он хочет использовать методы в цепочке прототипов Array, он может сделать это:
let domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
Таким образом, domNodes могут применять все методы в Array.
Несколько замечательных применений apply
1. Мат.макс.. Используйте его, чтобы получить самый большой элемент в массиве.
let max = Math.max.apply(null, array);
Точно так же, чтобы получить наименьший элемент в массиве, вы можете сделать это:
let min = Math.min.apply(null, array);
2. Реализовать комбинацию двух массивов. До оператора распространения ES6 мы могли сделать это с помощью Array.prototype.push.
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
Array.prototype.push.apply(arr1, arr2);
console.log(arr1); // [1, 2, 3, 4, 5, 6]
Использование привязки
Наконец, давайте поговорим о привязке. Объяснение MDN: метод bind() создает новую функцию, которая при вызове устанавливает ключевое слово this в предоставленное значение. И когда вызывается новая функция, данный список параметров используется как несколько первых элементов последовательности параметров исходной функции.
Его синтаксис следующий:
Function.bind(thisArg[, arg1[, arg2[, ...]]])
Метод bind похож на apply и call в том смысле, что он также может изменять указатель this в теле функции. разница в том,Возвращаемое значение метода привязки — это функция, и ее необходимо вызвать позже для выполнения.. С другой стороны, apply и call вызываются немедленно.
Рассмотрим следующий пример:
function add (a, b) {
return a + b;
}
function sub (a, b) {
return a - b;
}
add.bind(sub, 5, 3); // 这时,并不会返回 8
add.bind(sub, 5, 3)(); // 调用后,返回 8
Если первый параметр bind имеет значение null или не определен, это относится к окну глобального объекта.
Суммировать
Основная функция вызова и применения — изменить контекст выполнения объекта и немедленно его выполнить. Они немного по другому пишутся по параметрам.
Bind также может изменить контекст выполнения объекта.В отличие от call и apply, возвращаемое значение представляет собой функцию, которую необходимо вызвать позже для выполнения.
Напоследок поделитесь удобным методом запоминания call and apply, который я видел на Жиху:
Кошки едят рыбу, собаки едят мясо, а Ультрачеловек сражается с маленькими монстрами.
Однажды собака захотела съесть рыбу
кошка ест рыбу зовет (собака, рыба)
Собака съела рыбу
Кот стал штрафом и хочет драться с монстрами
Ультрачеловек Ударь маленького монстра Звонок (кошка, маленький монстр)
Кошки тоже могут сражаться с монстрами
PS: Добро пожаловать, чтобы обратить внимание на мою общедоступную учетную запись «Super Brother Front-end Small Stack», чтобы обменяться идеями и технологиями.