Хлопці, чи може хтось пояснити контекст використання callта applyметоди в Javascript?
Навіщо використовувати callі applyзамість того , щоб викликати функцію безпосередньо?
Відповіді:
Ви використовуєте callабо applyколи ви хочете передати інше thisзначення функції. По суті, це означає, що ви хочете виконати функцію так, ніби це метод певного об'єкта. Єдина різниця між ними полягає в тому, що callочікуються параметри, розділені комами, тоді як applyочікуються параметри в масиві.
Приклад зі сторінки Mozillaapply , де конструктори прив’язані ланцюгами:
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властивості.
Toy.prototype = new Product();? Я перевірив це, і видалення цих рядків, здається, не впливає на кінцевий результат.
Toy.prototype = new Product();але залишив Food.prototype = new Product();, то тепер їжа успадковує продукт, а Іграшка ні. Я також додав метод до прототипу Продукту і зателефонував йому з Food and Toy, щоб зробити відсутність успадкування більш очевидним (просто відкрийте консоль і запустіть код, Food може викликати метод, успадкований від Product, але Toy не може і видає помилку) .
Тільки якщо ви використовуєте callабо applyможете змінити thisконтекст усередині функції.
На відміну від інших мов - у JavaScript thisне посилається на поточний об'єкт, а на контекст виконання, і його може встановити абонент.
Якщо ви викликаєте функцію за допомогою newключового слова this, правильно буде посилатися на новий об'єкт (усередині функції конструктора).
Але у всіх інших випадках - thisбуде посилатися на глобальний об'єкт, якщо не встановлено явно через виклик
obj.whatever();синтаксис.
Ви використовуєте, .call()коли хочете, щоб функція виконувалася з іншим thisзначенням. Він встановлює thisзначення, як вказано, встановлює аргументи, як вказано, а потім викликає функцію. Різниця між .call()функцією та просто її виконанням полягає у значенні thisпокажчика під час виконання функції. Коли ви виконуєте функцію нормально, javascript вирішує, яким thisбуде вказівник (зазвичай глобальний контекст, windowякщо функція не викликається як метод на об'єкті). Коли ви використовуєте .call(), ви точно вказуєте, на що ви хочете thisбути встановлені.
Ви використовуєте, .apply()коли аргументи, які ви хочете передати функції, знаходяться в масиві. .apply()також може призвести до виконання функції із певним thisзначенням. .apply()найчастіше використовується, коли у вас невизначена кількість аргументів, які надходять з іншого джерела. Часто використовується, щоб передавати аргументи з одного виклику функції іншому, використовуючи спеціальну локальну змінну, argumentsяка містить масив аргументів, переданих поточній функції.
Я вважаю корисними сторінки посилань на MDN для .call () та .apply () .
Якщо у вас є досвід роботи з jQuery, ви будете знати, що більшість функцій використовують thisоб'єкт. Наприклад, collection.each(function() { ... });
усередині цієї функції, "this"посилається на об'єкт ітератора. Це одне з можливих застосувань.
Я особисто використовував .apply()для реалізації черги запитів - я штовхаю масив аргументів у чергу, і коли настає час її виконання, я беру елемент і передаю його як аргументи для функції обробника, використовуючи .apply(), таким чином, роблячи тоді очищувач коду, якщо потрібно передавати масив аргументів як перший аргумент. Це ще один приклад.
Загалом, просто майте на увазі, що такі способи виклику функції існують, і одного дня ви можете знайти їх зручними для реалізації вашої програми.
Якщо у вас є досвід роботи, 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
Я не можу згадати жодної нормальної ситуації, коли встановлення thisArg на щось інше є метою використання apply.
Метою 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]
thisArgчас дзвінка,apply()іcall()це, здається, є суттю вашого запитання. Вам потрібно зрозуміти примітив виклику функції в Javascript