Reputation: 15145
I am kind of new to OOP in JS. I would like to know why when creating sub-objects, this stops referring to the main object AFTER the second level of subobjects.
function Clase()
{
this.__construct = function()
{
this.paginator();
alert('__construct finished');
};
this.paginator = function()
{
this.paginator.title = function()
{
this.paginator.title.set_offsets = function()
{
alert('paginator.title.set_offsets executed!');
};
};
this.paginator.title(); //instantiating
alert('subobject paginator created');
};
this.__construct();
}
var instancia = new Clase();
instancia.paginator.title.set_offsets();
The error is: this.paginator is undefined.
And now, if I use closures, it works perfectly:
function Clase()
{
self = this;
this.__construct = function()
{
this.paginator();
alert('__construct finished');
};
this.paginator = function()
{
self.paginator.title = function()
{
self.paginator.title.set_offsets = function()
{
alert('instancia.paginator.title.set_offsets() executed');
};
};
self.paginator.title();
alert('this.paginator created');
};
this.__construct();
}
var instancia = new Clase();
instancia.paginator.title.set_offsets();
So, AFAIK after some point, "this" stops refering to the class "Clase" and refers to something else. If so, is it a good practice to use closures this way?
Is it also correct to start the class with self = this; and from then on use ONLY "self"? for instance: http://jsfiddle.net/byGRX/
Upvotes: 0
Views: 195
Reputation: 2599
You don't lose reference to the this
object, here's what happens:
For example:
function Class() {
this.func1 = function () {
this.func1.func2 = function () {
alert('Works!');
};
};
this.func1.func2();
}
x = new Class();
Now, the reason you get an error saying that func2
doesn't exist is because the function object for func2
isn't constructed until you call func1
:
function Class() {
this.func1 = function () {
this.func1.func2 = function () {
alert('Works!');
};
};
this.func1();
this.func1.func2();
}
x = new Class();
And now it works.
EDIT:
So, why doesn't this work:
function Class() {
this.func1 = function() {
this.func1.func2 = function() {
this.func1.func2.func3 = function() {
alert('works!');
};
this.func1.func2.property = 5;
};
};
this.func1();
this.func1.func2();
}
x = new Class();
x.func1.func2.func3();
Basically, what your trying to do is add a property named property
and a method named func3
to the function object of func2
, but the problem is that func2
isn't constructed before calling func1
. It's the same as doing:
function Class() {
this.func1 = function() {
this.func1.func2 = function() {};
};
this.func1.func2.func3 = function() {
alert('works!');
};
this.func1.func2.property = 5;
this.func1();
this.func1.func2();
}
x = new Class();
x.func1.func2.func3();
If you want it to work you need first construct the function object for func2
by calling func1
:
function Class() {
this.func1 = function() {
this.func1.func2 = function() {};
};
this.func1();
this.func1.func2.func3 = function() {
alert('works!');
};
this.func1.func2.property = 5;
// this.func1.func2();
}
x = new Class();
x.func1.func2.func3();
alert(x.func1.func2.property);
Upvotes: 0
Reputation: 35399
You lose the reference to the "original" this
when you nest function
s. To remedy do the following:
function Clase() {
var that = this;
this.paginator = {
title: {
set_offsets: function() {
alert('paginator.title.set_offsets executed!');
}
}
};
};
var foo = new Clase();
foo.paginator.title.set_offsets();
Upvotes: 3