A
A
Alex Efros2011-03-16 20:39:27
JavaScript
Alex Efros, 2011-03-16 20:39:27

JavaScript: what does Function.call.apply(...) do?

In the JavaScript Garden , in the "Functions / The arguments Object" section, there is this line: JS experts, please explain what is the meaning of the Function.call.apply entry? As far as I understand, both call and apply are normal methods of the Function object, and calling Function.call.apply is the same as calling Function.apply. As a last resort, if for some reason it is important here to call .apply from a new empty object of type Function returned by a call, then it turns out that Function.apply.apply could just as well be done?

// Result: Foo.prototype.method.call(this, arg1, arg2... argN)
Function.call.apply(Foo.prototype.method, arguments);


Answer the question

In order to leave comments, you need to log in

4 answer(s)
M
mnasyrov, 2011-03-16
@powerman

Everything is simple :). The purpose of this trick is to write a wrapper for foo() that calls bar() in the given context and with the arguments arg1, arg2 passed in without any unnecessary body movements.
In the traditional way, it would look like this. Or, for an arbitrary number of arguments: Instead of this salad, use the call.apply trick: It works like this: aplly calls Function.call on the bar object with the parameters passed to foo. That is, we get the following for the very first example with context and arg1, arg2: What we need.
function bar(arg1, arg2) {}
function foo(context, arg1, arg2) {
bar.call(context, arg1, arg2);
}

function bar() {}
function foo() {
var context = arguments[0];
var args = Array.prototype.slice.call(arguments, 1); //делаем массив аргументов для bar
bar.apply(context, args);
}

function foo() {
Function.call.apply(bar, arguments);
}

bar.call(context, arg1, arg2)

A
Anatoly, 2011-03-16
@taliban

call changes this inside the called function.
example
var obj = {};
Array.push.call( obj, 1 );
The push method will be called on the Array object, but inside this method this will point to the object that I specified as the first parameter, that is, my obj;
Why is it and how to use it?
For example, the setTimeout and setInterval functions, when they call a method, they call this method without being tied to the parent, respectively, in the called methods there will be this = window.
With the help of call, you can change this and forcefully specify what you want. This is like a simple example

M
Mikhail Davydov, 2011-03-16
@azproduction

In the example, they made it so as not to separate the first element of the array - to make it beautiful.
At one time, I broke my brain when I took it apart, here are examples that explain everything:

Function.prototype.call.apply(function(a,b){console.log([this,a,b])}, [NaN,{},4], {}, 0);
(function(a,b){console.log([this,a,b])}).apply(NaN, [{},4], {}, 0);
// Оба выдают [NaN {}, Object {}, 4]
// NaN будет объектом т.к. был передан в качестве первого параметра

Function.prototype.call.call(function(a,b){console.log([this,a,b])}, [NaN,{},4], {}, 0);
(function(a,b){console.log([this,a,b])}).call([NaN,{},4], {}, 0);
// Оба выдают [[NaN, Object {}, 4], Object {}, 0]
// Массив [NaN,{},4] уже объект поэтому не преобразуется в объект

G
gaelpa, 2011-03-16
@gaelpa

Why: to create an object method that accepts the "this" substitution as the first parameter.
Function.apply.apply will have a different effect because apply and call take different parameters.
Why at a higher level: comes to mind only as an option for building a library of utilities for organizing a “beautiful” call and not polluting the namespace.
When called, the following happens, if anyone is interested:

// в контексте примера
var a={ toString:function(){return 'a'} };
Foo.method(a,1,2,3);

1. apply is passed: object "Foo.prototype.method", parameters [a,1,2,3]
2. Foo.prototype.method.call(a, 1,2,3) is called, i.e. Foo.prototype.method on behalf of object a
3. call console.log(a, 1,2,3); because this===a
PS full original example:
Another trick is to use both call and apply together to create fast, unbound wrappers.
function Foo() {}

Foo.prototype.method = function(a, b, c) {
    console.log(this, a, b, c);
};

// Create an unbound version of "method" 
// It takes the parameters: this, arg1, arg2...argN
Foo.method = function() {
    // Result: Foo.prototype.method.call(this, arg1, arg2... argN)
    Function.call.apply(Foo.prototype.method, arguments);
};

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question