2

I am new to javascript and I am trying to implement a complicated data structure which requires modification of scope inside various functions. Then, I came across function.prototype.bind(). At first, I thought it was very useful. But, some of the results are unexpected. So, I wrote a demo code for testing and here is the code.

(function () {

    this.t = 9.8765432

    this.a = (function(){
        this.t = 3.14159
        this.b = (function(){return this.t;}).bind(this)
        this.c = (function(){
            this.t=1.23456
            this.d=(function(){return t;}).bind(this)
            return this
        })()
        return this
    })()

    console.log(this.a.b()) //My guess was 3.14159, at the end it is 1.23456
    console.log((this.a.b.bind(this))()) //My guess was 9.8765432, at the end it is 1.23456
    console.log(this.a.c.d()) //My guess was 1.23456, at the end it is 1.23456
    console.log((this.a.c.d.bind(this))()) //My guess was 9.8765432, at the end it is 1.23456

    return this
})();

Sadly, I guessed all the results incorrectly. This indicates I don't have enough understanding of this function. Can anyone explain it to me?

3
  • Modifying scope is pretty complicated for someone who's new. Heck, I'm experienced and I still won't touch scope. Are you sure you need to do it? Commented May 1, 2018 at 15:12
  • Note that the code heavily relies on the fact that it is not run in strict mode: jsfiddle.net/2wd83dw5. Outside of strict mode the this context of a function invocation which is not on an object (e.g. (function() { ... })() is undefined. Commented May 1, 2018 at 15:15
  • I am trying to emulate a filesystem in javascript. To implement mkdir and ls, I added functions corresponding to the two commands using bind(this) in each directory object. Commented May 1, 2018 at 15:19

1 Answer 1

3

You're not creating any objects for this to refer to. Thus this just refers to the global window object everywhere in your code (it would be undefined in strict mode). Since you only have one object, you only have one t property which has most recently been assigned the value 1.23456. The previous assignments were overwritten by the most recent assignment.

Try your test with the new keyword instead of IIFEs at each scope. This will create three separate objects for this at different scopes, instead of using the global object:

new function () {

    this.t = 9.8765432

    this.a = new function(){
        this.t = 3.14159;
        this.b = function(){return this.t;}.bind(this);
        this.c = new function(){
            this.t = 1.23456;
            this.d = function(){return this.t;}.bind(this);
            return this;
        };
        return this;
    };

    console.log( this.a.b() ); // My guess was 3.14159
    console.log( this.a.b.bind(this)() ); // My guess was 9.8765432
    console.log( this.a.c.d() ); // My guess was 1.23456
    console.log( this.a.c.d.bind(this)() ); // My guess was 9.8765432

    return this;
};

Your first and third guesses are correct. Your second and fourth guesses would be correct if the function hadn't already been bound. Calling bind on an already bound function has no effect on it. Removing the inner calls to bind gives you exactly what you expect:

new function () {

    this.t = 9.8765432

    this.a = new function(){
        this.t = 3.14159;
        this.b = function(){return this.t;};
        this.c = new function(){
            this.t = 1.23456;
            this.d = function(){return this.t;};
            return this;
        };
        return this;
    };

    console.log( this.a.b() ); // My guess was 3.14159
    console.log( this.a.b.bind(this)() ); // My guess was 9.8765432
    console.log( this.a.c.d() ); // My guess was 1.23456
    console.log( this.a.c.d.bind(this)() ); // My guess was 9.8765432
    
    return this;
};

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

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.