Подтвердить что ты не робот

Контекст для использования вызова и применения в Javascript?

Ребята могут объяснить какой-либо контекст для использования методов call и apply в Javascript?

Зачем использовать call и apply вместо прямого вызова функции?

4b9b3361

Ответ 1

Вы используете call или apply когда вы хотите передать другое значение this функции. По сути, это означает, что вы хотите выполнить функцию, как если бы это был метод определенного объекта. Единственное различие между ними состоит в том, что call ожидает параметры, разделенные запятыми, а apply ожидает параметров в массиве.

Пример из страницы Mozilla apply, где построены цепочки:

function Product(name, price) {
    this.name = name;
    this.price = price;

    if (price < 0)
        throw RangeError('Cannot create product "' + name + '" with a negative price');
    return this;
}

function Food(name, price) {
    Product.apply(this, arguments);
    this.category = 'food';
}
Food.prototype = new Product();

function Toy(name, price) {
    Product.apply(this, arguments);
    this.category = 'toy';
}
Toy.prototype = new Product();

var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);

Что Product.apply(this, arguments) делает следующее: конструктор Product применяется как функция внутри каждого из конструкторов Food и Toy, и каждый из этих экземпляров объекта передается как this. Таким образом, каждый из Food и Toy теперь имеет свойства this.name и this.category.

Ответ 2

Только если вы используете call или apply, вы можете изменить контекст this внутри функции.

В отличие от других языков - в JavaScript this не относится к текущему объекту - скорее к контексту выполнения и может быть задан вызывающим.

Если вы вызываете функцию с помощью ключевого слова new this, это будет правильно ссылаться на новый объект (внутри функции конструктора).

Но во всех остальных случаях - this будет ссылаться на глобальный объект, если он явно не установлен через вызов

Ответ 3

Используется .call(), если вы хотите заставить функцию выполнить с другим значением this. Он устанавливает значение this, как указано, устанавливает аргументы как указано, а затем вызывает функцию. Разница между .call() и просто выполнением функции - это значение указателя this, когда функция выполняется. Когда вы обычно выполняете функцию, javascript определяет, что будет указывать указатель this (обычно глобальный контекст window, если функция не вызывается как метод для объекта). Когда вы используете .call(), вы точно определяете, к чему вы хотите установить this.

Вы используете .apply(), когда аргументы, которые вы хотите передать функции, находятся в массиве. .apply() также может вызвать выполнение функции с определенным значением this. .apply() чаще всего используется, когда у вас есть неопределенное количество аргументов, исходящих из какого-то другого источника. Он часто используется, чтобы передать аргументы из одного вызова функции другому, используя специальную локальную переменную arguments, которая содержит массив аргументов, которые были переданы вашей текущей функции.

Я нашел страницы ссылок MDN для .call() и .apply().

Ответ 4

Если у вас есть опыт работы с jQuery, вы узнаете, что большинство функций используют объект this. Например, collection.each(function() { ... }); Внутри этой функции "this" ссылается на объект итератора. Это одно возможное использование.

Я лично использовал .apply() для реализации очереди запросов - я нажимаю массив аргументов в очередь, и когда придет время для его выполнения, я беру элемент и передаю его в качестве аргументов для обработчика используя .apply(), тем самым делая код более чистым, если необходимо передать массив аргументов в качестве первого аргумента. Это еще один пример.

В общем, просто имейте в виду, что существуют способы вызова функции, и вы когда-нибудь найдете их удобными для использования для реализации вашей программы.

Ответ 5

Я не могу придумать какую-либо нормальную ситуацию, когда настройка thisArg для чего-то другого - это цель использования apply.

Цель применения - передать массив значений функции, которая хочет эти значения в качестве аргументов.

Он был заменен в обычном повседневном использовании оператором спреда.

например.

// Finding the largest number in an array
`Math.max.apply(null, arr)` becomes `Math.max(...arr)`

// Inserting the values of one array at the start of another
Array.prototype.unshift.apply(arr1, arr2); 
// which becomes 
arr1 = [...arr2, ...arr1]

Ответ 6

Если у вас есть опыт работы с Object Oriented Programming, тогда вызов и применение будут иметь смысл, если вы сравните его с наследованием и переопределите свойства или метод/функции родительского класса из дочернего класса. Что похоже на вызов в javascript, как показано ниже:

function foo () {
  this.helloworld = "hello from foo"
}
foo.prototype.print = function () {
  console.log(this.helloworld)
}

foo.prototype.main = function () {
  this.print()
}


function bar() {
  this.helloworld = 'hello from bar'
}
// declaring print function to override the previous print
bar.prototype.print = function () {
  console.log(this.helloworld)
}

var iamfoo = new foo()

iamfoo.main() // prints: hello from foo

iamfoo.main.call(new bar()) // override print and prints: hello from bar