Roli Agrawal
Roli Agrawal

Reputation: 2466

Understanding inner function with this in Javascript

I recently started to learn Javascript while doing some experiments with code stuck in this code:

var k = {
    ab: "hi",
    func: function() {
        console.log("inner1" + this.ab);
        (function() {
            console.log("inner2 " + this.ab)
        }())
    }
};
k.func();

This code giving me result "inner1 hi" and "inner2 undefined".

I'm not getting the reason why its undefined in second console.log?

Upvotes: 1

Views: 76

Answers (5)

bpavlov
bpavlov

Reputation: 1090

In your example 'this' means two different things based on scope. You could play with this sample code. Maybe it would help you to understand the basics.

var k = {
    ab: "hi",
    func: function() {
        var me = this; // save 'meaning of this' in variable me.
        console.log("inner1" + this.ab);
        (function() {
            console.log("inner2 " + me.ab)
        }())
    }
};
k.func();

Upvotes: 1

Ry-
Ry-

Reputation: 225124

The this of a function is bound when you call it, depending on how you call it. Calling it as a value instead of a property – (expression)() instead of object.method() – will result in this being set to the global object, or undefined in strict mode.

There are two methods on function objects that call the function with an explicitly-specified this: call and apply. You can use the former here.

(function() {
    console.log("inner2 " + this.ab);
}.call(this));

That will forward the calling function’s this to the inner function.

Alternatively, you can just assign this to a variable.

var that = this;

(function() {
    console.log("inner2 " + that.ab);
}());

Upvotes: 7

Kunj
Kunj

Reputation: 2018

@minitech and @Issac very well explained the issue and solution. Another method to get property at any level is by object. In your code it is:

var k = {
    ab: "hi",
    func: function() {
        console.log("inner1" + this.ab);
        (function() {
            console.log("inner2 " + k.ab)
        }())
    }
};

k.func();

Upvotes: 2

TryinHard
TryinHard

Reputation: 4118

You don't have any reference for using this in second function. Instead you can use:

(function() {
    console.log("inner2 " + this.ab)
}.call(this))

Upvotes: 1

Isaac
Isaac

Reputation: 11805

var k = {
    ab: "hi",
    func: function() {
        console.log(this,"inner1" + this.ab);
        (function() {
            console.log(this,"inner2 " + this.ab)
        }())
    }
};
k.func();

Executing the anonymous function changes the instance, to persist the context do:

var k = {
    ab: "hi",
    func: function() {
        console.log("inner1" + this.ab);
        (function() {
            console.log("inner2 " + this.ab)
        }.bind(this).call())
    }
};
k.func();

Upvotes: 2

Related Questions