[Перевод] Как использовать apply(💅), call(📞), bind(➰) в JavaScript

JavaScript

Оригинальная ссылка:Как использовать методы apply(💅), call(📞) и bind(➰) в JavaScript
Оригинальный автор:Ashay Mandwarya
Переводчик:JintNiu
Рекомендуемая причина:apply,callа такжеbindОни часто встречаются на собеседованиях и ежедневном кодировании, и становится особенно важным понять и освоить их использование.

В этой статье мы обсудим цепочку прототипов функций вapply,callа такжеbindметоды, ониJavaScriptнаиболее важные и часто используемые понятия вthisКлючевые слова тесно связаны.

Поэтому, чтобы понять то, что описано в этой статье, вы должны быть знакомы сthisПонятие и использование ключевых слов. может относиться кэта статья.

Примечание переводчика: см.:Это руководство по JavaScript

чтобы понятьapply|call|bind, нам сначала нужно понятьJavaScriptсерединаFunction, конечно, предпосылка, что вы можете использовать клинкерthis.

Functions

FunctionКонструктор создает новыйFunctionобъект. Если вы вызываете конструктор напрямую, вы можете динамически создать функцию в глобальной области видимости.

существуетJavaScript, функция — это объект, который может бытьapply,callа такжеbindспособ вызова.

Чтобы проверить, является ли функцияFunctionобъект, мы можем использовать следующий код, чтобы судить, фрагмент кода возвращаетtrue.

(function () { }).constructor === Function ? console.log(true) : console.log(false);

ГлобальныйFunctionОбъекты не имеют собственных методов или свойств. Но поскольку это сама функция, к ней можно получить доступ с помощьюFunction.prototypeЦепочка прототипов наследует некоторые методы и свойства. — МДН

Вот методы в цепочке прототипов функций:

  • Function.prototype.apply()
  • Function.prototype.bind()
  • Function.prototype.call()
  • Function.prototype.isGenerator()
  • Function.prototype.toSource()
  • Object.prototype.toSource
  • Function.prototype.toString()
  • Object.prototype.toString

В этой статье мы обсудим только первые три.

Подать заявку 💅

apply()Является важным методом в прототипе функции, используется для вызова других функций, параметры задаютсяthisи массив (или подобный массиву объект).

Массивоподобные объекты могут ссылаться наNodeListили внутри функцииargumentsобъект.

Это означает, что мы можем вызвать любую функцию и явно указать, когдаthisуказывает на.

грамматика

function.apply(this,[argumentsArray])

возвращаемое значение

вернутьthisУказывает на результат вызова функции.

описывать

apply()способ сделать объектxФункция/объект может использоваться другим объектомyпередача.

пример

1.

var array = ['a', 'b'];
var elements = [1, 2, 3];
array.push(elements);
console.log(array);  // ['a', 'b', [1, 2, 3]]

В приведенном выше коде, когда мы помещаем массивpushПри вводе другого массива весь массив рассматривается как один элемент напрямуюpushвходить. Но если мы хотим преобразовать массивelemenntsэлементы вpushв массивarrayв? Конечно, есть много способов сделать это, здесь мы используемapply().

var array = ['a', 'b'];
var elements = [1, 2, 3];
array.push.apply(array, elements);
console.log(array); // ["a", "b", 1, 2, 3]

В этом примере используйтеapplyобъединяет данный массив, аргумент является массивомelements,thisуказать на переменнуюarray, который реализует массивelementsЭлементы вpushВойтиthisобъект указал на (array)середина. Окончательный возвращаемый результат состоит в том, что каждый элемент во втором массивеpushВойтиthisуказано в массиве.

2.

var numbers = [53, 65, 25, 37, 78];
console.log(Math.max(numbers)); //NaN

JSсерединаmaxФункция используется для нахождения максимального значения для данного элемента. Но, как мы видим, если заданное значение является массивом, возвращаемый результат равенNaN. Конечно,JavaScriptЕсть много способов решить эту проблему, здесь мы используемapply.

var numbers = [53, 65, 25, 37, 78];
console.log(Math.max.apply(null, numbers)); //78

когда мы используемapplyпередачаMath.max(), ожидаемый результат был получен.applyБудуnumbersВсе значения в виде отдельных параметров перед вызовомmaxОбработать и, наконец, вернуть наибольшее значение в массиве.

Примечательно, что мы используемnullвместоthis. Поскольку предоставленный аргумент представляет собой массив чисел, даже если он используетсяthis, он по-прежнему будет указывать на тот же массив и в конечном итоге даст тот же результат. Поэтому в данном случае можно опуститьthis, используйте вместоnullзаменять. То есть,applyв функцииthisПараметр является необязательным параметром.

Звоните 📞

call()метод используется для вызова функции с заданными параметрамиthisи несколько индивидуально заданных последовательностей параметров.

Это означает, что мы можем вызвать любую функцию и явно указать, когдаthisуказывает на.

Это то же самое, чтоapplyочень похоже, единственное отличиеapplyпринимает аргументы в виде массивов или массивоподобных объектов, аcallПараметры предоставляются отдельно.

грамматика

function.call(thisArg,arg1,arg2,...)

возвращаемое значение

вернутьthisУказывает на результат вызова функции с заданными аргументами.

описывать

call()способ сделать объектxФункция/объект может быть вызвана объектомyпередача.

пример

1.

function Product(name, price) {
    this.name = name;
    this.price = price;
}
function Pizza(name, price) {
    Product.call(this, name, price);
    this.category = 'pizza';
}
function Toy(name, price) {
    Product.call(this, name, price);
    this.category = 'toy';
}

var pizza = new Pizza('margherita', 50);
var toy = new Toy('robot', 40);
console.log(toy); // Toy {name: "robot", price: 40, category: "toy"}
console.log(pizza); // Pizza {name: "margherita", price: 50, category: "pizza"}

Это пример цепочки конструкторов. Как видите, каждая функция вызываетсяProductконструктор и использоватьcallБудуProductСвойства объекта такие же, какPizzaа такжеToyсвязаны.

при созданииPizzaа такжеToyэкземпляр объекта и вывод, результат показывает, что он имеетname,priceа такжеcategoryтри свойства, но мы определили толькоcategoryатрибут. в то время как атрибутыnameа такжеpriceпотому что это ужеProductобъект определен и применен, что может бытьProductПолучены связанные конструкторы объекта. Наследование может быть достигнуто путем небольшого изменения приведенного выше кода.

2.

function sleep(){
    var reply=[this.animal,'typically sleep between',this.sleepDuration].join(' ');
    console.log(reply); // I typically sleep between 12 and 16 hours
}
var obj={
    animal:'I',sleepDuration:'12 and 16 hours'
};
sleep.call(obj);

В приведенном выше коде мы определяемsleepфункция, содержащая массивreply, массив состоит изthisСостоит из элементов, полученных в результате адресации атрибутов, которые определены в отдельных объектах вне функции.

Функции вызоваsleep, параметры которогоobj. можно увидетьthis.animalа такжеthis.sleepDurationвзятые отдельноobjсвойства и выведите полное предложение.

Привязать➰

когдаbind()При вызове метода создается новая функция с первым параметромthisи предоставить заданную последовательность аргументов при вызове новой функции. — МДН

Примечание переводчика:bind()Метод создаст новую функцию, называемую функцией привязки, когда эта функция привязки вызывается, функция привязки будет передана при ее создании.bind()Первый параметр методаthis, второй и последующие параметры, а также параметры самой среды выполнения связанной функции вызывают исходную функцию в том же порядке, что и параметры исходной функции.

грамматика

function.bind(this,arg1,arg2,arg3,...)

возвращаемое значение

вернутьthisУказывает на результат вызова копии функции, аргументы которой являются заданными аргументами.

описывать

bindметод сcallМетод аналогичен, главное отличие в том, чтоbindвозвращает новую функцию, аcallНе возвращайся.

Согласно спецификации ECMAScript 5,bindФункция, возвращаемая методом, представляет собой особый тип функционального объекта, называемый связанной функцией (BF). BF содержит исходный функциональный объект, который выполняется при вызове BF.

пример

var x = 9;
var module = {
    x: 81,
    getX: function () {
        return this.x;
    }
};
console.log(module.getX()); // 81
var retrieveX = module.getX;
console.log(retrieveX()); // 9
var boundGetX = retrieveX.bind(module);
console.log(boundGetX()); // 81

В приведенном выше коде мы определили переменнуюxи объектmodule, в этом объекте также определено свойствоxи возвращениеxфункция стоимости.

при вызове функцииgetXКогда он возвращает определение объектаx, не в глобальной областиx.

Другая переменная объявляется в глобальной области видимости и называетсяmoduleв объектеgetXфункция. Но поскольку переменная находится в глобальной области видимости,getXсерединаthisУказывая на глобальную областьx, который возвращает 9.

Наконец определите другую переменнуюboundGetX, переменная вызывает функциюretrieveX, в отличие от предыдущего, на этот раз функцияretrieveXс объектомmoduleСвязывание, возврат - это объектxценность . Это потому чтоbindв функцииthisуказывает на объектxзначение вместо глобальногоx, поэтому выводится 81.

В заключение

Теперь, когда мы увидели основное использование трех вышеуказанных методов, вы можете задаться вопросом: зачем использовать 3 разных метода для выполнения одной и той же задачи. Чтобы решить эту проблему, вы должны неоднократно практиковаться в том, как их использовать в разных сценариях, и иметь более полное представление о том, когда их использовать и как их лучше использовать, что определенно сделает ваш код более ясным и мощным.

Если вам понравилась эта статья, нажмите Похвалить, добавьте платеж ~