4

First, See my code plz.

function test(){

    this.item = 'string';

    this.exec = function(){
        something();
    }

    function something(){
        console.log(this.item);
        console.log('string');
    }
}

And I made class and call 'exec function', like this code

var t = new test();

t.exec();

But result is...

undefined
string

I wanna access from something function to test.item.

Have you any solution?

LostCode
  • 533
  • 2
  • 6
  • 25

4 Answers4

6

You need to call something with apply so that this is properly set inside of something:

function test(){

    this.item = 'string';

    this.exec = function(){
        something.apply(this);
    }

    function something(){
        console.log(this.item);
        console.log('string');
    }
}

As @aaronfay pointed out, this happens because this doesn't refer to the object that new test() created. You can read more about it here, but the general rule is:

If a function is invoked on an object, then this refers to that object. If a function is invoked on its own (as is the case in your code), then this refers to the global object, which in the browser is window.

go-oleg
  • 19,272
  • 3
  • 43
  • 44
  • 3
    It's worth noting that the `function something() {}` alters the context of the `this` keyword, and that's why it's no longer as expected. `apply` effectively "applies" the context of `this` to another function. – aaronfay Oct 02 '13 at 06:13
2

You have many choices, but I recommend the last one.

var item = 'string'

or

this.exec = function(){
    something.apply(this, []);
}

or

var that = this;
function something(){
    console.log(that.item);
    console.log('string');
}
Chokchai
  • 1,684
  • 12
  • 12
2

this.item in something() isn't what you think it is.

The this value is different. In this case, it's the global object.

The best solution, in my opinion, is to declare a variable with a reference to this, that can be accessed inside the inner function.


function test() {
    var that = this; // a reference to 'this'

    function something() {
        console.log(that.item); // using the outer 'this'
        console.log('string');
    }

    this.item = 'string';

    this.exec = function(){
        something();
    }
}
Joe Simmons
  • 1,828
  • 2
  • 12
  • 9
  • 1
    OK, I Know. That have another scope, yes. But, I don't want use like 'var that = this;'. Anyway, Thanks to your answer! @Joe Simmons – LostCode Oct 02 '13 at 06:27
  • You're welcome. I will say that using `var that = this;` is much more dynamic and easy to type in big applications. I'm the creator of a JS library similar to jQuery, so I know that. – Joe Simmons Oct 02 '13 at 06:30
  • That was very helpful. I'll use that at next project! Thanks again! @Joe Simmons – LostCode Oct 02 '13 at 06:35
  • You're welcome. PM me if you have any problems with your project :) – Joe Simmons Oct 02 '13 at 06:40
1

Why not just define something like this:

Fiddle

function test(){

    this.item = 'string';

    this.exec = function(){
        this.something();
    }

    this.something = function(){
        console.log(this.item);
        console.log('string');
    }
} 

var t = new test();
t.exec();
// output:
// string 
// string
d.raev
  • 9,216
  • 8
  • 58
  • 79