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?

smallbone
  • 37
  • 5
  • 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) – Mike 'Pomax' Kamermans Aug 11 '17 at 04: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](https://en.wikipedia.org/wiki/Rubber_duck_debugging) exactly why you are trying to assign the result of an IIFE to the property `say`. –  Aug 11 '17 at 05: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). – smallbone Aug 11 '17 at 05: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 =) – Mike 'Pomax' Kamermans Aug 11 '17 at 16:57

2 Answers2

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.

ASDFGerte
  • 4,695
  • 6
  • 16
  • 33
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();
guest271314
  • 1
  • 15
  • 104
  • 177