0

Consider the following very simplified example:

var some_module = {
    func_a: function() {
        return 'a';
    },
    func_b: function(character) {
        if (character == 'b') {
            console.log(this); //refers to window
            return this.func_a;
        } else {
            return 'X';
        }
    },
    func_c: function() {
        console.log(this); //refers to some_module
        return "abcdefgh".replace(/[abc]/g, this.func_b);
    }
};
some_module.func_c();

This fails because in func_b, "this" refers to window because of the call context (as far as i know). I am aware of workarounds, that usually work when nesting functions, however how can I get it to work in this case where the function is used as a callback in .replace()?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Stefan
  • 2,164
  • 1
  • 23
  • 40
  • You ought to take a deep breath and step back and make sure you really understand what `this` means and where it comes from. There are plenty of good tutorials, including answers right here on SO, such as http://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work. This question has been asked in one form or another probably dozens of times. –  May 31 '15 at 16:17

2 Answers2

1

Try use .bind

return "abcdefgh".replace(/[abc]/g, this.func_b.bind(this));

Or store reference to this,

func_c: function() {
   var _this = this;

   return "abcdefgh".replace(/[abc]/g, function (char) {
       return _this.func_b(char);
   });
}

Example - 1 Example - 2

Oleksandr T.
  • 76,493
  • 17
  • 173
  • 144
0

You could use the ES7 binding operator:

return "abcdefgh".replace(/[abc]/g, ::this.func_b);

Note the double colon ::. This is supported by Babel if given the right flags. See https://github.com/zenparsing/es-function-bind. See also http://wiki.ecmascript.org/doku.php?id=strawman:bind_operator.

The main purpose of this enhancement is to stop the flow of identical questions here on SO from people who can't get their heads around this and wonder why setTimeout(this.foo, 1000) doesn't work.