3

var obj = {
    say: function() {
        function _say() {
            console.log(this);
        }
        return _say.bind(obj);
    }()
};

obj.say();

the code result is log out the global or window, I want to know why the bind method doesn't bind 'this' to the obj object context?

4
  • The real question here is if you need this binding, why are you not using an actual object-with-prototype? The code you show tries to ladle "instance logic" into "instance-of-nothing" code, which you can do, it's JavaScript, but it's also really... silly? What are you actually trying to do with this code? (or with code like this) Commented Aug 11, 2017 at 4:51
  • (1) Put a breakpoint on the return _say.bind(obj); line. (2) When it stops there, examine the value of obj. (3) Think real hard. (4) Explain to your rubber ducky exactly why you are trying to assign the result of an IIFE to the property say. Commented Aug 11, 2017 at 5:25
  • Thanks for your comments, @Mike 'Pomax' Kamermans. This code is a just practice, I want to know why 'this' is global when using bind(undefined). Commented Aug 11, 2017 at 5:49
  • it's a reasonable question if you're spec diving, but the code you show is worth never using in any real file you intent to actually work with, or worse, have others work on =) Commented Aug 11, 2017 at 16:57

2 Answers 2

1

During assignment the variable obj still does not have any value. As such, your call to bind is equivalent to .bind(undefined) which behaves the way you observed.

To be more specific, this referring to window is because of OrdinaryCallBindThis doing the following steps (non strict mode):

[...]
If thisArgument is undefined or null, then
[...]
Let thisValue be globalEnvRec.[[GlobalThisValue]].

You can check in the chrome debugger that [[BoundThis]] is indeed undefined after your call.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your answer, @ASDGerte. But if the _say function bind 'this' to 'undefined', why the 'this' in the obj.say() bind to global/window instead of obj?
@smallbone edited. I was just searching for that after answering as well :)
I got it! Thank you so much.
0

You are invoking the function immediately. Remove parenthesis following say function. If you are expecting to call the function without two consecutive parenthesis obj.say()() use .call() instead of .bind()

var obj = {
  say: function() {
    function _say() {
      console.log(this);
    }
    return _say.call(this);
  }
};

obj.say();

Comments

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.