3

I tried the following in the Google Chrome console:

> function t1(f) { return f(1); }
> function t2() { return this+1; }
> t1(t2.call)
TypeError: object is not a function

Why does this not work? Is there a way to define a function in lieu of Function.prototype.call that would work here?

2 Answers 2

5

It doesn't work because when you're passing t2.call, you're actually just passing .call. In other words, it doesn't remember the object from which it was passed.


To accomplish what you wanted, you can use .bind().

t1(t2.call.bind(t2))

This binds the t2 function as the this value of .call, which means you'll be calling .call as though you had done this:

t2.call

...which is what you wanted.


The .bind method is not supported in IE8 and lower, as well as some other older browsers, but you can implement a mostly complete shim in those cases.


FYI, if you need this a lot, you could bind .call as the calling context of .bind to shorten it a bit.

var callBind = Function.prototype.bind.bind(Function.prototype.call);

So now you have a .bind() function with .call() bound as its calling context. When you invoke it, it will be as if you were doing this:

.call.bind(/* the function */)

So callBind() will return a function with the function bound as the calling context of .call, just like we did above. So you'd use it like this:

t1(callBind(t2))
Sign up to request clarification or add additional context in comments.

3 Comments

"It doesn't work because when you're passing t2.call, you're actually just passing .call. In other words, it doesn't remember the object from which it was passed." Could you explain this a bit more if possible? I don't quite get why it doesn't remember the object.
@Ray: .call is just a property on an object. The only relationship between the object and the function is that the function is assigned to the property. When you pass t1.call to another function, you're retrieving the function from the t1 object, but only passing the function, not the object. It would be like if I handed you something, and you took it somewhere. The relationship between myself and that thing is broken once I let go, and that thing has no connection back to me.
Ahh ok I think I get it. It's like with a regular object/propery say o ={name: "foo"}. Then you call f(o.name) it's just that property .name that's sent with no attachment/reference to o anymore... yeah?
2

Why do things the hard way? Can't you just send over the callback function t2 to t1 and use call() inside t1?

function t1(f) { 
    return f.call(1); 
}

function t2() { 
    return this+1; 
}

t1(t2);

1 Comment

Hmm, it was really more for personal edification than anything else. Thanks for the suggestion though.

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.