When is "this" evaluated? - javascript

For the following piece of code
a.b = function c(){
return function e(){
return this;
};
};
d = a.b();
What will the value of d() be? This might not be a very good example, but I am just confused about what "this" will refer to.
Thanks,

Seeing as d will now equal a FUNCTION, "this" will be evaluated to whatever function calls it. It hasn't actually been evaluated yet.
At the end of execution, d='function e() { return this; }', so the moment you execute d() is when this will be evaluated.

From your code d is not the same as the "this". d will be a the function e, since you are setting d to be return value of the function call a.b() which returns a function, so
d = function e(){
return this;
}
Now the value of this depends upon how you call this function d. this will be evaluated when this function is called. If you just call it like d() this will be the global Window Object.
and lets say if I have
obj ={foo:1, bar:2};
and I call like this
d.call( obj )
this will be the object obj. the call() method is used to call a function on any object, the passed object behaves as this inside that function.
I know Javascript this is really confusing and it isn't easy to get your head around it.
May be this can help http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx

this is an implicit parameter to all functions.
See apply and call
If you know python, this is just like self, but not explicitly written and always there

this is normally the caller of a function
$('.image').each(function(index){
alert($(this).attr('href'));
}
I think a.b() will return a
see http://remysharp.com/2007/04/12/jquerys-this-demystified/

this is a reference to the object on which method was called.
d() is similar window.d() (if there is no with instruction)

Assuming d() was called immediately after the last line of your snippet d() will return the global object: window if you're in a browser.
However both of these are true:
d.call(a) === a;
d.call(a.b.prototype) === a.b.prototype;
which is to say that this is defined by what is passed in as the first argument to call.

Related

Function returning function and no reference

My question is about this function:
function d() {
function e() {
alert('E');
}
return e;
}
d()();//alerts 'E'
When function d is called first time function e is returned, however, nothing holds reference to the returned value( function e in this case), and this returned value should be lost. So, how does this d()() work ? It's not a closure according to my understanding. Thank you !
The call to d (which is d() in that last line) returns e, and then the last () immediately calls that function.
Consider
function n() { return 5; }
console.log(n() + 1); // 6
Nothing holds the return value from the call to n(), and yet the return value can be used in the addition operation. The return value from the call to d() can similarly be used as a reference to a function in a function call expression, which is exactly what happens in your code.
To put it another way, d() returns a reference to a function (e). In order to call a function, all you need is a reference to a function taken from somewhere, and a parenthesized argument list. That's what d()() gives you.
You don't need a named reference to a function in order to use it. You can apply an operator to the result of any expression in place, and the () function call is just another operator.
So it's little different from performing addition on the result of a function call.
function returnTwo() {
return 2;
}
console.log(returnTwo() + 40);
Here we don't store the result of returnTwo(), but we can still use it as the left operand of the + operator. So with the function call in your example, you're doing the same thing.
function d() {
function e() {
alert('E');
}
return e;
}
d()();
//alerts 'E'
It doesn't need a reference because it is explicitly transformed into the returned value. Unless stored, the result of a JavaScript Expression( a sequence of interpreted variables, functions, and/or operations that returns a value ) will be fully evaluated and then removed from memory. The key is that it has to be fully evaluated. You can almost think of functional execution as horizontal Russian Nesting Dolls. The JavaScript expression is:
d()();
So it begins left-to-right with:
d()
which is executed and returns:
function e() { ... }
which turns the line into:
function e() { ... }()
which is then executed, alerts, and returns:
//nothing
The full Expression is completed. There is nothing left for it to do. The reference isn't stored anywhere and immediately after this expression is resolved everything that was returned from its evaluations is thrown away.

Understanding JavaScript this with private function and self executing function

I was reading Angus Croll understanding JS this blog and found this
var a = {
b: function() {
var c = function() {
return this;
};
return c();
}
};
a.b();//window
To me it looks like, at the time of invoking c, c was inside b. that should be the invoking context (correct me, if i am wrong). when it executes, Why context(this) of c() is window?
there is another example i found in that blog
var a = {
b: function() {
return (function() {return this;})();
}
};
a.b(); //window
why context of b is window? Does anonymous function always run in the global context?
Here's a good way to understand this (pun intended):
The value of this inside a function is determined by the way the function is called. With one exception, it doesn't have to do with where the function is defined, what other functions it may be nested inside, what object it was defined as part of, what kind of function it is, or any of that.
When you call a function using a method call like foo.bar() or foo[bar](), this inside the function is the foo object.
When you call a function with an ordinary function call like foo(), this in the function is the window object, or if the function uses strict mode it is undefined.
That's the one exception - if the function itself or its surrounding code has "use strict"; it changes this for a plain function call. For good code that shouldn't make a difference - you shouldn't be writing code that depends on this being the window object anyway.
Otherwise, what you care about is what object this refers to in a method call. And that's always determined by how the function is called, not how it's defined.
Let's go through your first example.
When you call a.b(), you're calling b as a method of the a object. So inside the b function, this is the same as a.
As it happens, it doesn't do us any good to know that, because the b function never does anything with this. All it does is call c() as an ordinary function. So inside c, this is the window object, or it would be undefined if you were in strict mode.
The c function simply returns its this value, or window. And that is also the return value from b. So that's why you see window as the result: it all comes from how the code calls the b and c functions.
Now about the second example: well, that's just terribly obfuscated code, isn't it? Who would ever write this code and expect anyone to understand it at first glance?
So let's turn it into a more readable form. This line is the problem:
return (function() {return this;})();
Let's take out the parenthesized function expression:
(function() {return this;})
and assign it to a temp variable:
var temp = (function() {return this;});
We don't need the extra parentheses any more, and let's indent the code for readability:
var temp = function() {
return this;
};
and we can call that temp variable as a function in the return statement:
return temp();
Now we can put this back into the b function in the code example:
var a = {
b: function() {
var temp = function() {
return this;
};
return temp();
}
};
a.b(); //window
Hey! Doesn't that code look familiar? In fact, it's identical to the first example except for the name of the temp variable. So now you see why it works the same as the first one.
One key to look for is the new keyword, which establishes a new context. Don't see a new? Then the context hasn't changed, which means this hasn't changed. If you called this from within window, then that's your context, and that's your this. (This changes if you use call() or apply() with a scope, but that obviously doesn't apply here.)

Verifying my understanding of the scope chain

(Question 1)
In Flanagan's JS Definitive Guide, he defines the Function method bind() in case it's not available (wasn't available n ECMAScript 3).
It looks like this:
function bind(f, o) {
if (f.bind) return f.bind(o); // Use the bind method, if there is one
else return function() { // Otherwise, bind it like this
return f.apply(o, arguments);
};
}
He illustrates the use of it with an example (which I have modified to change the 3rd line from f.bind(o)):
function f(y) { return this.x + y; } // This function needs to be bound
var o = { x : 1 }; // An object we'll bind to
var g = bind(f, o); // Calling g(x) invokes o.f(x)
g(2) // => 3
When I first saw this, I thought "Wouldn't arguments refer to the arguments variable within the bind function we're defining? But we want the arguments property of the function we eventually apply it to, like g in the example above..."
I verified that his example did indeed work and surmised that the line return f.apply(o, arguments) isn't evaluated until var g = bind(f, o) up above. That is, I thought, when you return a function, are you just returning the source code for that function, no? Until its evaluated? So I tested this theory by trying out a slightly different version of bind:
function mybind2(f, o) {
var arguments = 6;
return function() { // Otherwise, bind it like this
return f.apply(o, arguments);
};
}
If it's simply returning tbe unevaluated function source, there's no way that it stores arguments = 6 when later evaluated, right? And after checking, I still got g(2) => 3. But then I realized -- if it's just returning unevaluated code, how is the o in return f.apply(o, arguments) getting passed?
So I decided that what must be happening is this:
The o and the arguments variables (even when arguments equals 6) are getting passed on to the function. It's just that when the function g is eventually called, the arguments variable is redefined by the interpreter to be the arguments of g (in g(2)) and hence the original value of arguments that I tried to pass on was replaced. But this implies that it was sort of storing the function as text up until then, because otherwise o and arguments would have simply been data in the program, rather than variables that could be overwritten. Is this explanation correct?
(Question 2) Earlier on the same page, he defines the following function which makes use the apply method to trace a function for debugging:
function trace(o, m) {
var original = o[m]; // Remember original method in the closure.
o[m] = function() { // Now define the new method.
console.log(new Date(), "Entering:", m); // Log message.
var result = original.apply(this, arguments); // Invoke original.
console.log(new Date(), "Exiting:", m); // Log message.
return result; // Return result.
};
}
Wouldn't the this here refer to the function that we're defining, rather than the object o? Or are those two things one and the same?
Question 1
For your first question, let's simplify the example so it's clear what being done:
function bind(func, thisArg) {
return function () {
return func.apply(thisArg, arguments);
};
}
What happens here is that a closure is created that allows the access of the original function and the value of this that is passed. The anonymous function returned will keep the original function in its scope, which ends up being like the following:
var func = function () {};
var thisArg = {};
func.apply(thisArg, [/*arguments*/]);
About your issue with arguments, that variable is implicitly defined in the scope of all functions created, so therefore the inner arguments will shadow the outer arguments, making it work as expected.
Question 2
Your problem is to your misunderstanding of the late binding of this -- this is one of the more confusing things about JavaScript to people used to more object-oriented languages that also have their own this keyword. The value of this is only set when it is called, and where it is called defines the value of this when it is called. It is simply the value of the parent object from where it is at the time the function is called, with the exception of cases where the this value is overridden.
For example, see this:
function a() {return this;};
a(); // global object;
var b = {};
b.a = a;
b.a(); // object b
If this was set when the function was defined, calling b.a would result in the global object, not the b object. Let's also simplify what happens with the second function given:
function trace(obj, property) {
var method = obj[property]; // Remember original method in the closure.
obj[property] = function () { // Now define the new method.
console.log(1); // Log message.
// Invoke original method and return its result
return original.apply(this, arguments);
};
}
What happens in this case is that the original method is stored in a closure. Assigning to the object that the method was originally in does not overwrite the method object. Just like a normal method assignment, the principles of the this value still work the same -- it will return the parent object, not the function that you've defined. If you do a simple assignment:
var obj = {};
obj.foo = function () { return this; };
obj.foo(); // obj
It does what was expected, returns the parent object at the time of calling. Placing your code in a nested function makes no difference in this regard.
Some good resources
If you'd like to learn more about writing code in JavaScript, I'd highly recommend taking a look at Fully Understanding the this Keyword by Cody Lindley -- it goes into much more detail about how the this keyword behaves in different contexts and the things you can do with it.
But this implies that it was sort of storing the function as text up until then, because otherwise o and arguments would have simply been data in the program, rather than variables that could be overwritten. Is this explanation correct?
No. this and arguments are just special variables which are implicitly set when a function is executed. They don't adhere to normal "closure rules". The function definition itself is still evaluated immediately and bind returns a function object.
You can easily verify this with:
var g = bind(f, o);
console.log(typeof g);
Here is a simpler example which doesn't involve higher order functions:
var arguments = 42;
function foo() {
console.log(arguments);
}
foo(1, 2);
I think you see that the definition of foo is evaluated like you'd expect. Yet, console.log(arguments) logs [1, 2] and not 42.
Wouldn't the this here refer to the function that we're defining, rather than the object o? Or are those two things one and the same?
this never refers to the function itself (unless you explicitly set it so). The value of this is completely determined by how the function is called. That's why this is often called "the context". The MDN documentation provides extensive information about this.
Reading material:
MDN - this
MDN - arguments

Why can we subsitute "foo" for "function (x) { return foo(x); }"

I was looking for lesser knows facts about JavaScript and I came across this piece, can anyone explain why the below code
function (x) { return foo(x); }
can be substituted with
foo
Tried to figure this out with the little knowledge of JavaScript which I had, but I didn't find the reason. Can anyone explain it?
Because
var bar1 = function (x) { return foo(x); };
var bar2 = foo;
And then
bar1(5);
bar2(5);
The first one will execute a function that will call foo(5), the second one will call foo(5) directly. Same end result.
The first is a function that takes one argument and returns whatever the result of foo with that argument is. The second is a function which takes one argument (presumably) and returns whatever the result of foo with that argument is (because it is the foo function).
The long version is just a wrapper around foo which doesn't add anything.
function(x){return foo(x);} actually is a nameless function which passes x to the function foo. The nameless function will return the result of foo(x) on the line return foo(x)
which is the same as calling foo(x) at the first place not form inside another function.
This code snippet assumes that foo is already a function in the current scope.
When you want to pass foo as a callback, you can do so directly:
function ITakeACallback(callback) {
callback(42); // and call it
}
ITakeACallback(foo);
So what you did here was pass to ITakeACallback an argument that happens to be a callable function; ITakeACallback indeed calls it.
Of course we can pass any callable function:
ITakeACallback(function(x) { return foo(x); });
This time we passed a function that accepts an argument, calls foo with that argument and returns the result. This is a roundabout way of calling foo directly, but the end result is the same.

Scope of this in javascript function

If you have the following code:
var global = this;
function A () {
function B () {
return this;
}
return B();
}
var C = new A();
C === global // true
Why does the this in function B refer to the global space and not the this of the object A?
The value of this is determined upon every function call. Because B is called without any context, the value of this is the global object.
It's possible to preserve this in an outer context by simply copying it:
function A() {
var x = this;
function B() {
return x;
}
return B();
}
this has nothing to do with scope, it's not a variable. It's a keyword that evaluates to the currently executing function's object context. The function's object context is determined by how you call it. It doesn't matter where or how the function is defined.
When you call a function like fn() then it is not in object context and the language wrongly attempts to work around it when it should just throw an error at the mere sight of this. This is somewhat fixed in strict mode where it would evaluate to undefined.
When you call a function as a property of some object I.E. obj.fn() then obj is bound to this for that call.
Since it would be clunky having to attach a function to some object just to get the right object context for the call, all functions inherit a .call method that allows you to specify the object context explicitly:
return B.call(this);
To accompany Pointy's correct answer:
The reasoning for this is because you can do whatever you want with functions.
You can return function B from function A, and save it as a global variable.
Or you could append function B as a method to an Object, or a dozen objects.
Or you could use it in an AJAX callback, or use it as a callback from a timer.
Because the engine doesn't know what's going to happen with function B, the language says that this refers to whatever the function is being called on, at the time it's called.
This adds a lot of dynamism to the language, but it also adds a lot of headache, if you're not sure what "this" is pointing to at any given time.
Rule of thumb:
If the function is directly attached as the method of an object, or a function is being called with .call or .apply and being fed a context, like myFunc.call(myObj), then this refers to window.

Categories

Resources