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 :-)

5
  • possible duplicate of What is the difference between call and apply? Commented May 30, 2013 at 17:56
  • Before going anywhere, your first line should read: function b(arg) { Commented May 30, 2013 at 18:07
  • @meagar I am not asking for difference.. Commented May 31, 2013 at 7:48
  • @joeytwiddle as per update, I do not want to modify b function. I want the solution to be elegant and with minimal effort :) Commented May 31, 2013 at 7: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. Commented Jun 1, 2013 at 12:38

6 Answers 6

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);
}
Sign up to request clarification or add additional context in comments.

Comments

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);
}

Comments

1

Try this one:

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

function b() {
    alert(arguments);
}

Comments

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.

Comments

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...) )

2 Comments

after adding the context "this" to call() it runs ;-)
Sorry, as per update I really do not want to modify functio b :)
-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

5 Comments

I hope, someone will explain why I should assume that arg and arguments are the same thing for the OP.
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 Only the OP knows what should be an option and what should not.
@poke what if the OP can't modify the body of b?
Funny. Makes it work without having to fix the b function!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.