Reputation: 73
All,
I have a bit of code that is essentially,
function b(){
console.log(this);
}
function a(){
console.log(this);
b();
}
Window.call(context, a);
The output looks like:
Object(context)
Window
It looks like the nonstandard context is only preserved when calling call, all subroutines where a context is not specified are called with the original context. Is there any way to invoke a function with context, having its entire execution stack occupy that same context?
Thanks,
Upvotes: 0
Views: 127
Reputation: 707766
There's a simple rule in Javascript. Every function call in Javascript sets a new value for this
. If you aren't making a method call such as obj.method()
or using .call()
or .apply()
, then this
is set back to the Global object or to undefined
in strict mode.
So, if you want to specifically control the value of this
in either of your function calls, then you will need to use .call()
or .apply()
or perhaps even .bind()
. There is no magic mode you can put Javascript in that will "preserve" this
when you call other functions. It just doesn't work that way.
Architecturally, if you really want a specific value of this
for several functions, then perhaps they should be methods on a common object because calling obj.method()
will automatically set this
to obj
or you can use .call()
or .apply()
to manually specify what you want the this
value to be for any function call.
In your code example, you could change:
function a(){
console.log(this);
b();
}
to this:
function a(){
console.log(this);
b.call(this);
}
And, b()
would get executed with the same value of this
as a()
.
Upvotes: 1
Reputation: 413826
You have to use .call()
or .apply()
:
function a(){
console.log(this);
b.call(this);
}
You cannot flip the runtime into a mode wherein it implicitly does that, so the direct answer to your question is "no".
If you have a bunch of functions and want to create versions that always have some particular value for this
, you can use .bind()
:
function b(){
console.log(this);
}
function a(){
console.log(this);
b();
}
a = a.bind(context), b = b.bind(context);
a(); // logs context from both functions
That'd be a pretty unusual thing to do but it would work. You'd be out of luck if you wanted to use the functions with a different object.
Upvotes: 3