var x = 5,
o = {
x: 10,
doIt: function doIt(){
var x = 20;
setTimeout(function(){
alert(this.x);
}, 10);
}
};
o.doIt();
Why is this referring to window object rather than o. I am inside the object o context, so it should print me 10 right?
The anonymous function is executed after 10ms, and the execution context is not in o at that time.
Check out the answers to How do JavaScript closures work?
var x = 5,
o = {
x: 10,
doIt: function doIt(){
var x = 20;
setTimeout(function(){
alert(this.x);
}, 10);
}
};
o.doIt();
All functions passed into setTimeout() are executed in the global scope. The value is 5 because this.x is the same as window.x
To make this alert 20, change this.x to simply x.
Related
This is a thought exercise. I'm not doing anything with this code and the purpose is to better understand how closures work.
Thought Process:
x === 10 in global scope.
outer() function is called.
x === 20 in the global scope and local scope.
inner() function is called.
right side of 'var x' is expressed.
In x + 20, because x is not defined in local scope, it searches outer scope and finds x === 20.
var x = 20 + 20.
var x === 40.
return x.
result === 40.
However, the answer is 20. Why is this?
var x = 10;
function outer () {
x = 20;
function inner () {
var x = x + 20;
return x;
}
inner();
}
outer();
var result = x;
When the inner() function is called, the first thing that happens is var x.
This means the JavaScript interpreter first creates a variable named x to which it assigns undefined.
Then it runs the assignment expression x + 20, which is equivalent to undefined + 20 which is NaN.
Your variable result has nothing to do with your inner() function as you have a local variable (because of that var x) and you ignore the returned result.
In other words, your code is equivalent to just this:
var x = 10;
function outer () {
x = 20;
}
outer();
var result = x;
Because your inner function defined a local var x which will hide the global variable outside. And the outer function uses the global variable x and assign it to 20. Obviously, the global x is 20. Javascript will define every local variable before you call the function in the prototype chain.
var x = 10;
function outer () {
x = 20;
function inner () {
alert(x); // alert undefined
var x = x + 20;
return x;
}
inner();
}
outer();
var result = x;
This question already has answers here:
Javascript scoping of variables
(3 answers)
Closed 6 years ago.
i have this code in java script
var x = 5;
function f(y) { return (x + y) - 2 };
function g(h) { var x = 7; return h(x) };
{ var x = 10; z = g(f) };
z value is 15. why?
the expression (x+y)-2 is being evaluated as (10+7)-2.
why does x get the value of 10, and not the value of the previous
block, where x = 7?
thanks for the help
You can completely delete the first assignment. It gets overwritten before you call g(f).
Also, you can remove the parentheses of the last block as there is no block scope in JS (actually block scope got introduced with let, so you wanna use that instead).
var x = 5;
function f(y) {
// global variable x is 10 -> 10 + 7 - 2 = 15
return (x + y) - 2;
}
function g(h) {
// x gets declared locally - local value will be used
var x = 7;
return h(x); // f gets called with y = 7
}
x = 10; //global x gets changed
z = g(f);
... and always place your semicolons. Even though they maybe look optional but in some cases they are obligatory.
Value of variable x is 10 at global execution context.
When function f is finally called the value of the argument which is y, this y actually represent value of x at local execution context of function g, here x is 7.
var x = 5;
function f(y) {
return (x + y) - 2 ;
}; // value of global var x is 10, value of parameter passed is 7
// this value comes from the local var x of g function's execution context.
function g(h) {
var x = 7; return h(x); };
{ var x = 10; z = g(f); };
console.log(z);
Let say we have a function that returns a function and bounds arguments to it:
function A(x, y){
return function(x, y){...}.bind(this, x, y);
}
And now we want to know if function A binds arguments correctly:
var resultedFunction = A();
var spy = sinon.spy(resultedFunction);
spy();
The question - is it possible to know if arguments are bound correctly? I've tried this, but it is an empty array
spy.firstCall.args
spy.getCall(0).args
I've finally come to some trick. If the returning function will be not an anonymous then we can spy it and check arguments later:
var obj = {
B: function(){
...
},
A: function(x, y){
return this.B.bind(this, x, y);
}
}
var x = 1, y = 2;
var spy = sinon.spy(obj, "B");
var resultedFunction = obj.A(x, y);
resultedFunction();
expect(spy.firstCall.args[0]).to.equals(x)
expect(spy.firstCall.args[0]).to.equals(y)
I have a question about how javascript stores functions internally.
Given this code:
var makesomething = function (x) {
var thing = {
x: x
};
thing.do = function () {
this.x++;
};
return thing;
};
var x1 = makesomething(1);
var x2 = makesomething(2);
Since I called the makesomething function twice, does that mean that there are essentially two copies of the "do" function or do the objects have reference to the same function but get called with different closure?
There are two copies, one created each time you called makesomething().
You'll notice that x1.do === x2.do is false.
If instead you do this:
var doIt = function() {
this.x++;
};
var makesomething = function (x) {
var thing = {
x: x
};
thing.do = doIt;
return thing;
};
var x1 = makesomething(1);
var x2 = makesomething(2);
Then both refer to the same function, and x1.do === x2.do will be true.
I'm trying to add 10 over and over for every invocation of d. It stays 20 every time, why?
function d() {
var c = [10];
c[0] += 10;
alert(c[0]); // always 20
}
d(); d(); d(); // supposed to be 20, 30, 40...
You create a new array and assign it to c each time the function is called. That resets it.
Move the assignment so it is outside the function (so it only runs once).
var c = [10];
function d() {
c[0] += 10;
alert(c[0]);
}
d(); d(); d(); // will be 20, 30, 40...
But globals are good source of bugs, so it is considered good style to wrap such things in closures to minimise the use of globals.
var d =(function () {
var c = [10];
function d() {
c[0] += 10;
alert(c[0]);
};
return d;
})();
d(); d(); d();
#Quentin already explained the reason for your problem and provided a solution. For more information about variable scope, have a look at the MDN JavaScript Guide.
As an alternative, you can assign the value to a property of the function:
function d() {
var c = d.c || (d.c = [0]); // initialize property if not set
c[0] += 10;
alert(c[0]);
}
What you have is local variable. Which gets initialized to 10 every time you invoke the function.
Try using global variable as
var c = [10];
function d() { c[0] += 10; alert(c[0]); // always 20 }
Why not just
var c = 10;
function d(){
c+=10;
alert(c);
}
d();d();d();