-2

I read this article http://web.archive.org/web/20110725013125/http://www.digital-web.com/articles/scope_in_javascript/.

In the last example, he provided the code:

var first_object = {
    num: 42
};
var second_object = {
    num: 24
};

function multiply(mult) {
    return this.num * mult;
}

Function.prototype.bind = function (obj) {
    //console.log(this); -> TypeError: Object #<Object> has no method 'log'
    var method = this,
        temp = function () {
            //console.log(this); -> RangeError: Maximum call stack size exceeded
            return method.apply(obj, arguments);
        };

    return temp;
}

var first_multiply = multiply.bind(first_object);
console.log(first_multiply(5)); // returns 42 * 5

var second_multiply = multiply.bind(second_object);
console.log(second_multiply(5)); // returns 24 * 5

Although he explained it, I still don't understand several things.

First, why we need do method = this, why this refers to the multiply function here and why this will change when the function temp is created on the next line? Second, why we need to create a function temp here? Third, I tried to print out the this by using console.log(). The strange thing is they both show some errors, could you tell me why?

PS: I used WebStorm IDE.

UPDATE: Please don't ignore the third question, why there are two errors when using console.log, thanks

CSnerd
  • 1,859
  • 7
  • 16
  • 39
  • Might not be an exact dupe, but still useful: http://stackoverflow.com/questions/111102/how-do-javascript-closures-work?rq=1 – Matteo Tassinari Dec 04 '15 at 17:22
  • Possible duplicate of [What does 'var that = this;' mean in JavaScript?](http://stackoverflow.com/questions/4886632/what-does-var-that-this-mean-in-javascript) – Matteo Tassinari Dec 04 '15 at 17:23
  • In `method = this`, the `this` is `foo` from `foo.bind(...)`, so it is the _method_ we are calling `.bind` on. We can't call it `this` inside `temp` because the `this` of `temp` may be different (e.g. if we do `o.bar = foo.bind(...)` then `this` in `temp` -> `o.bar` is `o`). We need `temp` because `.bind` should return a _function_, so we need some function to return. Please note `temp` is a poor choice of identifier name. – Paul S. Dec 04 '15 at 17:38
  • Looking more at the example here, this `.bind` implementation doesn't look great as it doesn't support `2+` args in `.bind`, does not set up the prototype chain correctly/at all and does not check first if `.bind` is already implemented before shadowing it. As for why `console.log` is failing, I can't say. May be your IDE, try in a browser instead. – Paul S. Dec 04 '15 at 17:43

2 Answers2

0

For regular functions, in JavaScript, what decides what this is going to be is how it's called. So it could be anything.

For example:

  • Calling it as a property of an obj, object is "this"
    • var obj = {run: multiply}; obj.run() // "this" will be "obj"
  • Calling it direct
    • multiply(); // "this" will be the global context, or null in strict mode
  • Using call or apply
    • multiply.call(something, 5); // "this" is "something"

Fat arrow functions, however, keep the same this as its containing function.

Function.prototype.bind = function (obj) {
    return () => {
        return this.apply(obj, arguments);
    };
}

Also, you do not need a temporary function in either case. You could just inline the temp variable.

Juan Mendes
  • 80,964
  • 26
  • 138
  • 189
  • This isn't good. you can't use arrow functions with `new` so binding constructors will fail. Where are your prototypes? where is the `2+` arg support? – Paul S. Dec 04 '15 at 17:49
  • @PaulS. I think you misunderstood the question, and my intent. The OP is not asking how to implement `Function.bind` properly. They are asking about how `this` works. That is what I'm addressing in the answer. I'm in no way suggesting the OP use that code as a polyfill. – Juan Mendes Dec 04 '15 at 17:55
0

var method = this;

Might be more clear if written:

var bindObj = this;

The bind function is really to assign which object to multiply function.

Lookup JavaScript Mixin might help explain more.

Leng
  • 1
  • 1