Reputation: 3968
I know I can access outer variable in function object but, here is what I'm stuck with.
zero = function (one) {
this.one = one;
this.two = {
three: {
four: function() {
one.test();
}
}
}
}
Sorry for the dirty code naming :(. But here's the test case.
foo = {
test: function() {
console.log('foo test');
}
}
bar = new zero(foo);
bar.two.three.four(); // prints 'foo test'
foo2 = {
test: function() {
console.log('another foo test');
}
};
bar.one = foo2;
bar.two.three.four(); // still prints 'foo test' instead of 'another foo test'
It looks like four
keeps the reference of one
since its creation not the reference of variable in bar
. And I cannot figure out how I can directly access to the outer variable. Thanks for reading my question.
Upvotes: 0
Views: 30
Reputation: 16020
Use
var zero = function (one) {
var _this = this;
this.one = one;
this.two = {
three: {
four: function () {
_this.one.test();
}
}
};
};
instead of
one.test();
That uses the closure variable instead of the publicly visible instance property.
When you do this:
this.one = foo2;
What you're actually doing is overwriting the publicly visible property. However, this is distinct from the argument to your function called one
, which is within the scope of your function created. one
is never changed in your code, therefore it's only natural that you're getting the valve from the initial assignment in your constructor function. Assigning a property to an object does not mean that they will be the same. If you do this inside a constructor:
function Test()
{ var test = {};
this.test = test;
test = { a: 1 };
console.log(this.test.a);
}
new Test; // undefined is logged
The reason why _this
is used in the new function is that the value of this
is only set when the function is called, not when it is defined. For example, take this behaviour:
function Example()
{ var _this = this;
this.test1 = { func: function () { return this; }
this.test2 = { func: function () { return _this; }
}
var instance = new Example;
var randomFunction1 = instance.test1.func;
var randomFunction2 = instance.test2.func;
instance.test1.func(); // the instance.test1 object
instance.test2.func(); // the actual instance
randomFunction1(); // the global object (though this will be undefined in strict mode)
randomFunction2(); // still the instance
The first is the way it is because the parent object of the method is instance.test1
, not instance
. By assigning the object reference at that time to a variable, we can permanently store this reference and refer to it any time that you like.
Note: you might want to use var
to declare your variable - this prevents implied globals which can be particularly nasty, and also assignments to undeclared variables are not permitted in strict mode.
Upvotes: 2