"this" in function invocation javascript - javascript

// Situation 1
var a = function A() {
this.x = 1;
var b = function B () {
this.x = 2;
console.log('Method B : x = ' + this.x);
};
console.log('Method A : x = ' + this.x);
b();
}
When I call a() , my result is
Method A : x = 1
Method B : x = 2
But if I delete "this.x = 2" as :
// Situation 2
var a = function A() {
this.x = 1;
var b = function B () {
console.log('Method B : x = ' + this.x);
};
console.log('Method A : x = ' + this.x);
b();
}
My result will be
Method A : x = 1
Method B : x = 1
I don't understand why
In situation 2 : "this" of function B is referenced to "this" of function A
But
In situation 1 : "this.x" of function A isn't changed when assign "this.x = 2" in function B
My code runs on Chrome v23

Since, this.x = 2 is in the definition of function B, it doesn't take place until B is called, not when it's defined. Try this version and see:
// Situation 3
var a = function A() {
this.x = 1;
var b = function B () {
this.x = 2;
console.log('Method B : x = ' + this.x);
};
console.log('Method A before B: x = ' + this.x);
b();
console.log('Method A after B: x = ' + this.x);
}

The reason this.x is being changed in both a and b is because they're both referencing the window object.
I think you're having a misconception with this one; this.x is being changed after the call to b. We can see this if we reverse the calls:
b(); // 2
console.log('Method A : x = ' + this.x); // 2

Calling b() like you do, will result in this referencing the global object (window within a browser environment).
That explains your behavior, your're writting basically window.x = 1;

You didn't call b() until after the value of A was printed. Therefore the value of x was 1 and THEN it was changed to 2 by b.
If you call b() before printing a() the output will be
Method A : x = 2
Method B : x = 2
As b() will first change value then a() will log
This is the function
var a = function A() {
this.x = 1;
var b = function B () {
this.x = 2;
console.log('Method B : x = ' + this.x);
};
b();
console.log('Method A : x = ' + this.x);
}
​Both a and b reference the window object window.x.

this is a special keyword in javascript and it depends on the context. In your case function B() is in the context of function A(). So if you don't overwrite this.x in function B() it'll be the value you assigned in function A().

Related

How can we pass one specific variable of a function as a callback?

I have recently picked up callback functions and trying to learn more on it.
I wanted to pass c from function y, which is the ultimate sum in function x as a parameter. Can this be done and how so?
function x(y){
console.log("x");
y();
}
x(function y(){
var a = 5;
var b = 45;
var c = a+b;
console.log(c);
});
You can simply return c from y and use it in x like so:
function x(y){
console.log("x");
let c = y();
console.log("c: ", c);
}
x(function y(){
var a = 5;
var b = 45;
var c = a+b;
console.log(c);
return c;
});

JavaScript Closure - trying to understand following code

Coming from Java background trying to make sense out of the following code.
From:
https://medium.freecodecamp.com/lets-learn-javascript-closures-66feb44f6a44#.cbk6c4e9g
For function bar(c), which line passes argument c into bar(c) as I don't see it here.
Thanks.
var x = 10;
function foo(a) {
var b = 20;
function bar(c) {
var d = 30;
return boop(x + a + b + c + d);
}
function boop(e) {
return e * -1;
}
return bar;
}
var moar = foo(5); // Closure
/*
The function below executes the function bar which was returned
when we executed the function foo in the line above. The function bar
invokes boop, at which point bar gets suspended and boop gets push
onto the top of the call stack (see the screenshot below)
*/
moar(15);
When your first statement of function call var moar = foo(5) is executed
moar variable will be function bar(c){var d=30;return boop(x+a+b+c+d);
check the snippet for understanding
var x = 10;
function foo(a) {
var b = 20;
function bar(c) {
var d = 30;
return boop(x + a + b + c + d);
}
return bar;
}
var moor=foo(10);
console.log(moor);
2.After this statement moar(15),your are actually passing 15 to the bar method
It will execute bar method with c as 15. Now this function would return boop(80) which would just be -80
var x = 10;
function foo(a) {
var b = 20;
function bar(c) {
var d = 30;
return boop(x + a + b + c + d);
}
function boop(e) {
return e * -1;
}
return bar;
}
var moar = foo(5)
console.log(moar(15));
Hope it helps
moar(15) passes 15 into bar which gets copied into parameter c.
The // Closure comment is misleading because it is more useful to think of the closure being configured at the point of declaration of a function.
The reality is that the pointer to the outer lexical environment is configured when a function object is instantiated, and then this pointer is then copied to the execution context associated with any invocations of said function object.

Variable hoisting examples [duplicate]

This question already has answers here:
Surprised that global variable has undefined value in JavaScript
(6 answers)
Closed 7 years ago.
Hi I have a snippet of code. I am confused about change of value x1 when I remove non-related part of same code. I searched about it and I came to know that it has to do with hoisting. But the value x1 is still unclear even with hoisting concept for me. Can someone please make me clear on this?
var x = 10;
function main() {
document.write("<br>x1 is " + x);
x = 20;
if (x > 0) {
var x = 30;
document.write("<br>x2 is " + x);
}
var x = 40;
var f = function(x) {
document.write("<br>x3 is " + x);
}
f(50);
}
main();
The output of this code is:
x1 is undefined
x2 is 30
x3 is 50
If I change this code to:
var x = 10;
function main() {
document.write("<br>x1 is " + x);
}
main();
The output is:
x1 is 10
So what is happening here is a common pitfall.
The simplest way to put this is. When you set var x = 30 inside your main function, you are actually redefining the scope that var x = 10 had for use inside this function. This has to do with how Javascript executes and scope.
By defining x inside the function, your scope for x has changed. Below is an example of what I mean and a version of your code that works
Example:
var test = 'test';
function run(){
console.log(test);
var test=1;
}
Your Code Updated:
var x = 10;
function main() {
console.log("<br>x1 is " + x);
x = 20;
if (x > 0) {
x = 30;
console.log("<br>x2 is " + x);
}
x = 40;
var f = function(x) { console.log("<br>x3 is " + x); }
f(50);
}
main();
Good question btw.
Since this is somewhat of a very interesting scope of how Javascript executes, consider the following code and its outputs to get the full idea
var test = 'test';
function run(){
console.log(test);
test=1;
console.log(test);
var test=2;
console.log(test);
}
console.log(test);
run();
console.log(test);
Very interesting to see how this reacts.
All variable and function declarations get "hoisted" or moved to the top of their scope. The undefined value for x is caused because the var x statement gets moved up to the top of main however the assignment = 30 does not.
So, your code will read more like this:
var x = 10; // x is 10
function main() {
var x; // x declaration is "hoisted"
document.write("<br>x1 is" + x); // x1 is undefined
x = 20; // x is 20
if (x > 0) {
x = 30; // x is 30
document.write("<br>x2 is" + x);// x2 is 30
}
x = 40; // x is 40
var f = function(x) { // x is 50
document.write("<br>x3 is" + x);// x3 is 50
}
f(50);
}
main();
You can read more about Hoisting here: JavaScript Scoping and Hoisting

Purpose of multiple assignment var x = this.x = function(){}?

In Mootools the following pattern occurs frequently:
var x = this.x = function(){}
For example:
var typeOf = this.typeOf = function(item){ ...
I understand multiple assignment results in function being assigned to both x and this.x. But I thought in the global scope x is implicitly this.x, so it seems redundant. Is this an optimization technique, or is there some other purpose to this pattern?
This is only redundant if this code isn't executed in a function.
If it's in a function, the var is local, even if the context (this) is the global one.
Look at this :
function a() {
var x = 1;
console.log(x)
}
function b() {
console.log(x); // fails
}
a();
b();
If you want to be both able to use x directly in a and have this.x in b, then you need the double assignation :
var x = this.x = 1;
I frequently use this pattern in big functions when I have a variable I use a lot and for which I prefer a direct access without this..
var x is not equals this.x, var x is a varible private of a js class and this.x is a public propertie, so the code create 2 ways for invoke a function
Here an example:
function exampleA() {
this.x = 1;
var x = 2;
this.show = function () {
alert("A.x:" + x);
alert("A.this.x:" + this.x);
};
}
function exampleB() {
var x = this.x = 1;
this.x +=1;
this.show = function () {
alert("B.x:" + x);
alert("B.this.x:" + this.x);
};
}
$(document).ready(
function () {
var example1 = new exampleA();
example1.show();
var example1 = new exampleB();
example1.show();
});

accessing an inner variable in a javascript object

Consider this errorful code:
x = {
y : "why",
z : function() {
return y + " zed";
}
}
The function z does not work: "ReferenceError: y is not defined".
Is there a way to access y from within the function z without fully specifying it as x.y?
I could of course rewrite this as
x = function() {
var self = this;
this.y = "why";
this.z = function() {
return self.y + " zed";
};
return this;
}();
... but gosh.
Simply use this if you call the function with x.z():
var x = {
y : "why",
z : function() {
return this.y + " zed";
}
};
DEMO: http://jsfiddle.net/hZxVu/
No, you will need to rewrite it as such. y is a property of that object, and you can't access it without the object - unlike accessing a variable (e.g. self in your rewrite) from a closure.
Of course, when you invoke the function as x.z(), the this keyword will point to the object too, so that you can write it as
return this.y + " zed";
as long as you always call the function in context of that object.
#VisioN has the straight-forward answer. It might help to visualize why this is necessary if you rewrite your code as such:
var x = {};
x.y = "why";
x.z = function() {return this.y + " zed"; };
alert(x.z());
Here y and z are properties of an object, but there is no functional closure scoping. You need the "this" keyword to access a property of the parent object.
Alternatively,
var x = function () {
var y = "why";
var z = function () { return y + " zed?"; };
return z();
};
alert(x());
This demonstrates functional scoping by accessing y without using this. Inside of x, y is known. Outside, it is not.
Using the revealing module pattern:
var x = (function () {
y = "why";
z = function() {
return y + " zed";
};
return {
"y": y,
"z": z
};
})();
//now you can call:
x.y // "why"
x.z() // "why zed"

Categories