4

Is there a reason why were not able to "NOT" define the first argument to Function.prototype.bind and have it retain the context its being called in.

I have a use case where its very useful to do this however it seems like passing null or undefined as the first argument binds the output function to Window.

Another way of saying this means it seems the current implementation of native bind does not allow you to not bind the context of the function and only bind argument prefixes to the bound the function.

Ex:

var a = function() { 
    this.foo = function() { console.log(this) }; 
    this.foo = this.foo.bind(undefined,1); 
};
var b = new a();
b.foo(); // Logs Window instead of the instance b;

This was tested in Google Chrome Version 27.0.1453.116 m

3
  • Couldn't you just write this.foo.bind(this,1); ? Commented Jun 27, 2013 at 23:28
  • Hey, When using the function on an object that's meant to be extended and perhaps even duplicated the function would still be bound to whatever was declared initially. The reason I want the function to naturally assume the this context of its caller is for the case when it is part of the prototype of an object and defined higher up in the inheritance hierarchy. Commented Jun 29, 2013 at 3:23
  • As mentioned earlier I want to skip the intermediate wrapping function call and use a native implementation to bind arguments to a function while having at retain the dynamic this context. Commented Jun 29, 2013 at 3:25

1 Answer 1

2

You'll need to create your own binder function to do that. The main reason for having .bind() was to deal with the non-lexically defined this. As such, they didn't provide any way to use it without setting this.

Here's a simple example you could use:

Function.prototype.argBind = function() {
    var fn = this;
    var args = Array.prototype.slice.call(arguments);

    return function() {
        return fn.apply(this, args.concat(Array.prototype.slice.call(arguments)));
    };
};

This is pretty bare-bones, and doesn't deal with the function being invoked as a constructor, but you can add that support if desired.


You could also enhance it to behave like the native .bind() unless null or undefined are passed as the first argument.

Function.prototype.argBind = function(thisArg) {
    // If `null` or `undefined` are passed as the first argument, use `.bind()`
    if (thisArg != null) {
        return this.bind.apply(this, arguments);
    }

    var fn = this;
    var args = Array.prototype.slice.call(arguments);

    return function() {
        return fn.apply(this, args.concat(Array.prototype.slice.call(arguments)));
    };
};
Sign up to request clarification or add additional context in comments.

2 Comments

Hey, thanks for the reply and code sample. My main motivation for asking the question was to avoid the extra non-native function call in the call stack that becomes a pain while debugging. Wondering if there is any native "hack" or function that could be used for partial application without having an intermediate function called. Thanks!
@ArmaanAhluwalia: Nothing that I'm aware of. AFAIK, the only way to bind arguments is with .bind(), and the only way to override the bound this value is when you invoke the bound function with new, which wouldn't seem helpful.

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.