This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 5 years ago.
This is an interview question! And I can't know the reason of it!
function fun(val) {
this.x = val;
return this;
}
var x = fun(1);
var y = fun(2);
console.log(x.x); //I can't understand this result.
console.log(y.x);
Well, I think that happens because "This" in the fun function refers to Window object not a local thing inside the function. so therefore you first call it by fun(1) and make the window.x = 1, and then call it by fun(2) and it becomes window.x = 2 .. then you console log it when both x and y are a reference to window ... and therefore both will have the same final value.
When you call a function the "normal" way, the this object points to the global object (window):
function testFunction () {
return this;
}
console.log(window === testFunction());
This means that what your function returns is the global object, and both variables x and y are references to the global object. Before it returns, it assigns a property x to the global object.
In the first function call, it assigns 1 to the property x of the global object. In the second function call, it assigns 2 to the same property. This is why you get 2 two times.
If you want this to refer to another object than the global one, you have to use call:
function testFunction (value) {
this.x = value;
return this;
}
var firstObject = {};
var secondObject = {};
var x = testFunction.call(firstObject, 1);
var y = testFunction.call(secondObject, 2);
console.log(x.x);
console.log(y.x);
console.log(x === firstObject);
console.log(y === secondObject);
console.log(window === testFunction());
Related
This question already has answers here:
Do let statements create properties on the global object?
(5 answers)
Closed 2 years ago.
The result is 10 when I use var keyword:
var x = 10;
let foo = {
x: 90,
getX: () => {
return this.x
}
}
console.log(foo.getX())
But undefined is the result when I use let keyword:
let x = 10;
let foo = {
x: 90,
getX: () => {
return this.x
}
}
console.log(foo.getX())
I cannot understand why there are two different results, when both of them have the same global scope.
As your object method, you used an arrow function, whose context (this value) is bound to the function in which you've declared them.
That is, your getX function's this value will be the global object (window).
Then you try to access the x property of that object, which is 10 (as global-scope var creates properties on the global object) in case of var.
However, let never creates a property on the global object, therefore in your second example, you get undefined.
Try it:
const object = {
method: () => this
}
console.log(object.method() === window) //true
var foo = 1
let bar = 2
console.log(foo, window.foo) // 1 1
console.log(bar, window.bar) // 2 undefined
This question already has answers here:
What does 'var that = this;' mean in JavaScript?
(6 answers)
Closed 3 years ago.
I've seen things like this:
function fnx(){
ctrl = this;
this.thisedVar = "thisedVar from fnx"
}
I'm trying to figure out what is it useful for. if that function is executed and then this is compared to ctrl, they are the same:
fnx();
console.log(this === ctrl) // true
That's why I don't understand what is the purpose of assigning this to a variable.
Can anyone explain it, please? Thanks.
var a = function() {
var THIS = this;
this.s = "Hello World";
this.runMe = function() {
window.setTimeout(function() {
console.log(this.s);
}, 100);
}
}
var a2 = function() {
var THIS = this;
this.s = "Hello World";
this.runMe = function() {
window.setTimeout(function() {
console.log(THIS.s);
}, 100);
}
}
b = new(a);
b.runMe();
b2 = new(a2);
b2.runMe()
Outputs:
undefined
Hello World
Class a (object b) returns undefined because that this is in the scope of the callback.
Class a2 (object b2) returns Hello World because that this belongs to the class a2.
When you assign a variable to a value without using var it refers to global variable. So if you are assigning this to ctrl it means the your are assigning Window obecjt this to a global variable `ctrl.
So when you compare ctrl with this (again Window) object, it is same since you are matching after function execution.
In most cases, the value of this is determined by how a function is called (runtime binding). It can't be set by assignment during execution, and it may be different each time the function is called.
You assign THIS to a variable so you save this value.
Read more: https://medium.com/tech-tajawal/javascript-this-4-rules-7354abdb274c
This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 3 years ago.
Initial question
The below code should return 1,3 since x: 1 is just present above return statement - however, it's returning 3,1. Why is this? Will it be same result when we use let and/or const.
It would be great if you guys explain, so that I can improve my fundamentals. Below is my code:
var x = 3;
var foo = {
x: 2,
baz: {
x: 1,
bar: function() {
console.log("this--->", this);
return this.x;
}
}
}
var go = foo.baz.bar;
alert(go());
alert(foo.baz.bar());
Update 1:
In the first case bar is considered as a closure which has access to the variables outside and prints 3:
bar: function() {
console.log("this--->", this);
return this.x;
}
The 'this' keyword will mean two different objects for the two function calls. You may see it by adding 'console.log(this);' before the return statement. Try using an arrow function instead!
When you assign foo.baz.bar to a var go, after the assignment go just holds a reference to the inner function. If it is then called from the outer scope then x = 3. In effect, the this within a function depends on the scope that the function is called from.
In the second case, when you call bar(), it is in the scope of the object it's called from within (i.e. foo.baz ), so this time the this within function bar() refers to baz, giving and so x = 1.
More on scope and this in javascript here
Here you can read up on Function.prototype.bind. This method should be able to help you out with your issue.
Check the code example below:
var x = 3;
const foo = {
x: 2,
baz: {
x: 1,
bar: function() {
return this.x;
}
}
}
//You're assigning a function definition to a variable, but this will not maintain scope:
const fn = foo.baz.bar;
//When called like this, bar() can be thought of as a method of foo.baz
console.log(foo.baz.bar()); //so we expect x = 1;
//You must properly bind your function reference to the desired "this" object:
const globalBound = fn; //which would be equivalent of: fn.bind(this);
const fooBound = fn.bind(foo);
const bazBound = fn.bind(foo.baz);
console.log(globalBound()); //x = 3
console.log(fooBound()); //x = 2
console.log(bazBound()); //x = 1
x = 'Now globalBound() will return a string';
foo.x = 'and so will fooBound(), but bazBound() will remain unchanged';
console.log(globalBound());
console.log(fooBound());
console.log(bazBound());
I encourage you to change var x = 3 to let x = 3 and check out your result.
//1st question
var x = 4,
obj = {
x: 3,
bar: function() {
var x = 2;
setTimeout(function() {
var x = 1;
alert(this.x);
}, 1000);
}
};
obj.bar();
//2nd question
function foo(a) {
arguments[0] = 2;
alert(a);
}
foo(1);
1.why it returns 4 instead of 1? i thought this.x refer to 1, but it seems wrong....i just dont understand why it returns 4
2.why it return alert 2 instead of 1, i thought i pass a to function a, and as far as i know, i pass 1 to function foo, and 1 should be alerted because of a(which is 1 when i pass)....i just don't understand why it alert 2
The runtime (in non-strict mode) invokes the setTimeout() callback with this bound to window (the global context), so this.x refers to the outer x.
The arguments object serves as a way to alias the formal parameters of a function. Setting the value of arguments[0] also sets the value of the first declared parameter to the function.
1. why it returns 4 instead of 1?
Notice the first initialization: var x = 4, which in non-strict mode attaches a property x to global object: window.x = 4.
setTimeout(function() {
var x = 1;
alert(this.x);
}, 1000);
setTimout() callback has this context as the global object. And actually calling alert(this.x) -> alert(window.x) -> alert(4).
2.why it return alert 2 instead of 1
arguments object represents the list of function arguments. When modifying it, you actually modify the arguments values: arguments[0] = 2 modifies first argument a = 2.
I understand the general idea behind the this keyword but I'm having trouble figuring out what it actually refers to in practice. For example, in both these example exercises, I guessed the wrong number.
for question1, I said that the alert would be '5', because it is referring to the this.x outside the anonymous function in the function.
In question2, I thought the alert would be 5 because this line
var alertX = o.alertX;
would bind the value 5 for property x inside the variable o to the new variable 'alertX' which becomes the function call in the next line: alertX();
Can you explain why I'm wrong?
var question1 = function() {
this.x = 5;
(function() {
var x = 3;
this.x = x;
})();
alert(this.x);
};
var answer1 = 3;
var question2 = function() {
this.x = 9;
var o = {
'x':5,
'alertX':function() { alert(this.x); }
};
var alertX = o.alertX;
alertX();
}
var answer2 = 9;
In the first case, when you invoke a method with no explicit receiver this is the Global object (the window in a web browser).
Similarly in the second case: even though the function is defined on the object, and you are inside another, by invoking the function with alertx() the this is set to the Global/window.
In short:
For foo.bar(), the this inside of bar will be foo.
For bar(), the this will be the Global object.
This includes so-called "self-invoking lambdas", i.e. (function(){ ... })().
For bar.call(whee) and bar.apply(whee), the this will be whee (because that's what these methods do).
Another example:
var o1 = { name:"o1", f:function(){ console.log(this.name) } };
var o2 = { name:"o2" };
o2.gogogo = o1.f;
o2.gogogo(); // Will output "o2"
These are good examples of how interesting this becomes in Javascript. this always refers to the context in which it was invoked / called, not simply where it is at that moment! question2 is a perfect example of it.
I'm assuming you are invoking these globally like so:
question1();
question2();
In question1:
You have an anonymous function that is ran after you first set x to 5. This anonymous function if not set to a variable, inside a function etc, would have this set to the global variable of window. But you have it within a function & set to variable question1. So when it runs itself, it sets this's (which is question1 function) x variable to 3.
In question2:
X is originally set to 9, this being question2 in this instance. Now the part that is throwing you off is that, even though within the o {} object you set x : 5. And your alertX function is calling this.x. All of this would lead you to think it will alert 5! But you are invoking your alert function outside of the o {} object, hence the this refers to question2 function again!
Put the following into your browser's console
var x = -1, log = function(){ // set up some stuff
if(console) if(console.log) return console.log.apply(console, arguments),undefined;
return alert(arguments.join(', ')),undefined;
},
question1 = function() {
this.x = 5; // question1.x is 5
(function() { // anonymous function fires in global 'window'
var x = 3; // so window.x is now 3
this.x = x; // this is window
})();
log('ans1',this.x,this); // see below
},
question2 = function() {
this.x = 9; // question2.x is 9
var o = {
'x':5, // o.x is 5
'alertX':function() { log('ans2',this.x,this); }
};
var alertX = o.alertX; // alertX === o.alertX
alertX(); // being called in global scope
// to make alertX have scope of question2
this.alertX = o.alertX; // this is question2
this.alertX(); // so we're calling from question2
},
a1 = new question1(), // note the new operator
a2 = new question2();
undefined;
And you'll get
ans1 5 question1
ans2 3 Window
ans2 9 question2