2

I run the below JS script but just find func2() output is foobar, not George, who can explain why func2 = func.bind(someuser) doesn't bind someuser to func?

var someuser = {
    name: 'George',
    func: function () {
        console.log(this.name);
    }
};
var foo = {
    name: 'foobar'
};
func = someuser.func.bind(foo);
func(); // output foobar
func2 = func.bind(someuser);
func2(); //output foobar
3
  • 1
    Maybe it's because its already been binded? Commented Jul 16, 2013 at 4:40
  • i don't get your question Commented Jul 16, 2013 at 4:40
  • @Shawn31313 You should post that as an answer btw. Commented Jul 16, 2013 at 4:43

3 Answers 3

4

From MDN:

The bind() function creates a new function (a bound function) with the same function body (internal Call attribute in ECMAScript 5 terms) as the function it is being called on (the bound function's target function) with the this value bound to the first argument of bind(), which cannot be overridden.

Basically this means that you can't call bind on an already bound function.

In your example, you'd have to do:

func2 = someuser.func.bind(someuser);
Sign up to request clarification or add additional context in comments.

Comments

2

I think what you want is a weak bind:

function weakBind(functable, context) {
    var GLOBAL = this;

    return function () {
        return functable.apply(this === GLOBAL ? context : this, arguments);
    };
}

Now you can do this:

var someuser = {
    name: 'George',
    func: function () {
        console.log(this.name);
    }
};

var foo = {
    name: 'foobar'
};

var func = weakBind(someuser.func, foo);
func(); // output foobar

var func2 = weakBind(func, someuser);
func2(); //output George

See the demo: http://jsfiddle.net/R79EG/


The problem with a normal bind is that once you bind an object to the this pointer it can't be overridden. The weak bind checks whether the this pointer is set to the GLOBAL object (in which case the default value is used). Otherwise it uses whatever the new this points to.


BTW in your case it's simply better to do this instead:

var someuser = {
    name: 'George',
    func: function () {
        console.log(this.name);
    }
};

var foo = {
    name: 'foobar'
};

var func = someuser.func.bind(foo);
func(); // output foobar

var func2 = someuser.func.bind(someuser);
func2(); //output George

This is better than weakBind because calling func2 would call func which would in turn call someuser.func. However using bind, calling func2 would directly call someuser.func.

1 Comment

+1 for suggesting a solution, rather than just telling him why it doesn't work.
0

You have already binded someuser.func.

You might want to setup the script differently.

Or use:

func = someuser.func.bind(foo);
func(); // output foobar
func2 = someuser.func.bind(someuser);
func2(); //output foobar

Don't try to rebind an already binded function.

5 Comments

"Should be:" --- why do you think so?
Because it would return "George"
are you sure you completely understand how .bind() works? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Dude you had the right answer in the comments but this makes no sense
And I do understand it. Not sure what I was doing.

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.