Страницы

Поиск по вопросам

суббота, 21 декабря 2019 г.

В чем принципиальная разница между call/apply и почему код так работает?

#javascript


Всем привет. Разрешите задать нубский вопрос по CALL/APPLY, может кто-то разжуёт
Как следует из многих туториалов и учебников call отличается от apply тем, что в
apply аргументом можно передать массив. А в call нет. 

var object = {
    "arr": ["Первый элемент",2,3,4,5],
    "func": function() {
        function awayFromMe(arr){
            console.log(arr);
        }
    awayFromMe.call (this, this.arr);
    awayFromMe.apply(this, this.arr);
    }
};
object.func();


То-есть я рассчитывал что call ничего не даст, a apply отработает, но вопреки моим
ожиданиям
call дал вывод массива:["Первый элемент", 2, 3, 4, 5]
apply дал вывод только первого элемента: "Первый элемент"

Почему так происходит?
    


Ответы

Ответ 1



foo.apply(thisArg, argsArray) foo.call(thisArg, arg1, arg2, ...) хотя синтаксис функции call() практически полностью идентичен функции apply(), фундаментальное различие между ними заключается в том, что функция call() принимает список аргументов, в то время, как функция apply() - одиночный массив аргументов. Т.е. разница только в том, что в apply вы передаёте аргументы в виде массива, а в call как есть: function test(a, b, c, d) { console.log(a, b, c, d); } // Последующие вызовы идентичны test.apply(null, [1, 2, 3, 4]); test.call(null, 1, 2, 3, 4); Другой пример: let a = [1, 2, 3]; // Один аргумент - массив console.log.call(console, a); // [1, 2, 3] // Три аргумента console.log.apply(console, a); // 1, 2, 3 // функция суммирует свои аргументы const sum = (...args) => args.reduce((c, a)=> c += a, 0); console.info('call', sum.call(null, a)); // sum([1,2,3]) = 0+'1,2,3' console.info('apply', sum.apply(null, a)); // sum(1,2,3) = 6

Ответ 2



Путём проб и ошибок, мне кажется я уловил тонкий смысл различия между call/apply и хотел бы им с Вами поделиться, может ещё будет такой(-ая) же как я. Итак, допустим, у нас есть простая заданная функция, которая возвращает сумму двух чисел: function sumTwoNumb(a, b){ return a + b; } Код крайне простой, мы передаём два аргумента в параметры функции, а она возвращает сумму. И допустим, нам надо вызвать эту функцию для двух элементов некоего массива. Если мы вызовем её как: sumTwoNumb.call(null, [100,150]), то получится так, что первый параметр a получит аргументом весь массив [100,150], а второй параметр, b не получит ничего и станет, соответственно, undefined. И в итоге функция вернёт результат сложения [100,150]+undefined, а это равно 100,150undefined. А если мы её вызовем так: sumTwoNumb.apply(null, [100,150]), то при входе в функцию первый параметр a получит нулевой элемент массива = 100, а второй параметр получит первый элемент массива = 150 и в итоге функция вернёт результат сложения 100 + 150, то есть верный. Уважаемые профессионалы, если я не прав, поправьте. Надеюсь, кому-то пригодится.

Ответ 3



Всё верно, call в первом аргументе возвращает массив, а apply распределяет элементы массива по аргументам, т. е. arr будет указывать на первый элемент Первый элемент.

Комментариев нет:

Отправить комментарий