1

i came across a situation where I need to call another function with .call() or .apply() like this:

function b() {
  alert(arg);
}

Then

function a(arg) {
  b.call();
}
a(123);

Function b is called, but doesnt' have access to arg. That's ok, I can pass scope.. yes?

function a(arg) {
  b.call(this);
}
a(123);

Still no - I can't access arg from function b. How can I do it?

UPDATE: I do not want to modify b function :-)

lukas.pukenis
  • 11,459
  • 12
  • 42
  • 78
  • possible duplicate of [What is the difference between call and apply?](http://stackoverflow.com/questions/1986896/what-is-the-difference-between-call-and-apply) – meager May 30 '13 at 17:56
  • Before going anywhere, your first line should read: function b(arg) { – joeytwiddle May 30 '13 at 18:07
  • @meagar I am not asking for difference.. – lukas.pukenis May 31 '13 at 07:48
  • @joeytwiddle as per update, I do not want to modify b function. I want the solution to be elegant and with minimal effort :) – lukas.pukenis May 31 '13 at 07:48
  • Then you should have accepted Engineer's answer! There is not much use using call or apply to pass the correct argument to `b` if your `b` function does not accept any arguments. – joeytwiddle Jun 01 '13 at 12:38

6 Answers6

6

You still need to pass the arguments via call (individually) or apply (as an array):

function a(arg1, arg2, arg3) {
  b.call(this, arg1, arg2, arg3);
  // or 
  b.apply(this, arguments)
  // or
  b.apply(this, [arg1, arg2, arg3]);
}

Of course, nothing about your situation suggests actually using call or apply: Just invoke the function yourself.

function a(arg) {
  b(arg);
}
meager
  • 209,754
  • 38
  • 307
  • 315
3

It’s not possible to “pass scope” or something like that. The scope of a function is determined when the function is created, so it can only access arg if it exists where b is defined.

If arg was part of this, then you could do this using call, i.e. make the this in b the same this as it is in a (of course this will modify whatever this actually refers to, which can have side effects you might not want to happen).

function a (arg) {
    this.arg = arg;
    b.call(this);
}

function b () {
    console.log(this.arg);
}

The other way would be to just pass the argument to b as an actual function argument. You can access all arguments of a function using arguments:

function b () {
    console.log(arguments);
}
poke
  • 307,619
  • 61
  • 472
  • 533
1

Try this one:

function a(arg) {
    b.apply(this, [arg]);
    // or
    // b.call(this, arg);
}

function b() {
    alert(arguments);
}
bitWorking
  • 11,824
  • 1
  • 30
  • 37
0

I'll guess the problem lies in b(). There's no 'arg' argument defined. Try:
function b(arg) { alert(arg); }
and

function a(arg) {
  b.call(this,arg);
}
a(123);

now it runs

(Update: the call needs the arguments ( context functionarg1, functionarg2...) )

dsuess
  • 4,769
  • 2
  • 20
  • 21
0

You failed to pass the arguments when you called b.

Function::call allows you to pass a fixed number of arguments:

function a(arg1,arg2) {
    return b.call(this,arg1,arg2);
}

Function::apply allows you to pass any number of arguments, as an array:

function a(arg1,arg2) {
    return b.apply(this,[arg1,arg2]);
}

// or

function a(arg1,arg2) {
    return b.apply(this,arguments);   // The magical 'arguments' variable
}

this is the context object, and is not the same thing as scope.

joeytwiddle
  • 24,338
  • 11
  • 107
  • 91
-2

Assuming that, for some reasons you can't modify the body of b , you can try something like this:

function a(arg) {
   eval("("+ b.toString() +")()");
}

DEMO

Engineer
  • 43,887
  • 11
  • 83
  • 90
  • I hope, someone will explain why I should assume that *arg* and *arguments* are the same thing for the OP. – Engineer May 30 '13 at 18:06
  • They are not the same, and OP does not imply that either (I doubt OP was even aware of `arguments`). While your code does what OP wants (evaluate `b` within a scope where `arg` is available), using `eval` should not be an option. – poke May 30 '13 at 18:09
  • @poke Only the OP knows what should be an option and what should not. – Engineer May 30 '13 at 18:13
  • @poke what if the OP can't modify the body of `b`? – Engineer May 30 '13 at 18:16
  • 1
    Funny. Makes it work without having to fix the `b` function! – joeytwiddle May 30 '13 at 18:17