Ridiculous scoping in Js [duplicate] - javascript

This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 1 year ago.
Can someone explain to me why the second function call returns undefined? I see no reason for that. The reference of the object method is stored in a variable, so it should be printed out. Why the result is undefined? The first function call is successful and the only difference is that the second one is stored in a variable.
const module = {
x: 42,
getX: function() {
return this.x;
}
};
//1 - returns 42
console.log(module.getX());
//2 - returns undefined
const unboundGetX = module.getX;
console.log(unboundGetX());

Because unboundGetX function is called by the global window variable, unboundGetX() it's like writing window.unboundGetX() so the this will refer to the global scope which is "window" object so it's also like you wrote return window.x which is logically "undefined".
it will be better to bind your scope to the same object like this :
const module = {
x: 42,
getX: function() {
return this.x;
}
};
console.log(module.getX());
const unboundGetX = module.getX.bind(module); // we bind getX function to module scope instead of the global scope (which is the window variable)
console.log(unboundGetX());

Related

arrow function vs normal function [duplicate]

This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
What does "this" refer to in arrow functions in ES6?
(10 answers)
Closed 1 year ago.
I'm new to javascript and having trouble understanding the difference between arrow function and normal function when including this keyword, here is the example I read from MDN:
var obj = { // does not create a new scope
i: 10,
b: () => console.log(this.i, this),
c: function() {
console.log(this.i, this);
}
}
obj.b(); // prints undefined, Window {...} (or the global object)
obj.c(); // prints 10, Object {...}
In this example arrow function b() can not access i attribute in the object because it references the window
var obj = {
count : 10,
doSomethingLater : function(){ // of course, arrow functions are not suited for methods
setTimeout( () => { // since the arrow function was created within the "obj", it assumes the object's "this"
this.count++;
console.log(this.count);
}, 300);
}
}
obj.doSomethingLater(); //log 11 on the console
However, in the second example, code within the arrow function can access the count attribute. Both functions are defined within the object but only the second function can access the object's attribute, could someone give me some hints why is that? Thanks in advance!

javascript - why is 'this' not referencing the object? code below [duplicate]

This question already has answers here:
How do JavaScript closures work?
(86 answers)
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 5 years ago.
I don't understand why this.name isn't the same as obj.name, basically why in this case this refers to the window object and not the obj object. In the code below, this.name is instantiated after obj.name..
function createNewPerson(name) {
var obj = {};
obj.name = name;
alert(this.name);
return obj;
}
Per MDN:
Inside a function, the value of this depends on how the function is
called. Since the following code is not in strict mode, and because
the value of this is not set by the call, this will default to the
global object , which is window in a browser.
So in your case you have this as the Window object, not the obj. You may get the obj context inside your function via binding it manually, for example:
function createNewPerson(name) {
console.log(this.name); // Hello
console.log(name); // World
}
var obj = {};
obj.name = 'Hello';
var salva = createNewPerson.apply(obj, ['World']);
But what you really need, as I can understand, is a function cunstructor and instantiating an object via new operator:
function createNewPerson(name) {
this.name = name;
}
var salva = new createNewPerson('Salva');
console.log(salva.name); // Salva

This values for arrow functions [duplicate]

This question already has answers here:
Methods in ES6 objects: using arrow functions
(6 answers)
How does the "this" keyword in Javascript act within an object literal? [duplicate]
(4 answers)
Closed 5 years ago.
I am trying to understand arrow functions in ECMAScript 6.
This is the definition I came across while reading:
Arrow functions have implicit this binding, which means that the
value of the this value inside of an arrow function is aways the
same as the value of this in the scope in which the arrow function
is defined!
According to the definition, I believe this for an arrow function should contain the same block level values that the arrow function was defined in.
Code:
var test = {
id: "123123",
k: {
laptop: "ramen",
testfunc: () => console.log(this)
}
}
console.log(test.k.testfunc);
However, I am getting this result from the code
function testfunc() {
return console.log(undefined);
}
What I thought I would get would be an output of:
{"laptop": "ramen"}
if I ran this
console.log(test.k.testfunc());
Let's transform into the equivalent ES5 code:
var test = {
id: "123123",
k: {
laptop: "ramen",
testfunc: function(){return console.log(this)}.bind(this)
}
}
Remember that this depends on how you call the function. The outer this isn't inside a function, so it will default to undefined in strict mode.
Simplified scenario below:
console.log(this) // undefined
var test = {
a: this // same `this` as above
}
You are defining the arrow function in the same scope that you defined var test. If you are defining test in the global scope, then the arrow function's context will be the global scope too.
If you are defining test inside of a method, the arrow function will share the method's context.
function method() {
const self = this;
const test = {
foo: () => console.log(self === this);
}
test.foo()
// console: true
}

Javascript global variable overriding local variable scope in a function [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 7 years ago.
I am little bit surprised after seeing the output of below javascript code. Still I do not have clue on why myObj variables have not been used inside own method. If I want to use myObj varaibles, what should be the way?
// The use of the "this" object inside the setTimeout function refers to the Window object, not to myObj
var highValue = 200;
var constantVal = 2;
var myObj = {
highValue: 20,
constantVal: 5,
calculateIt: function () {
setTimeout (function () {
console.log(this.constantVal * this.highValue);
}, 2000);
}
}
myObj.calculateIt(); // 400
//The "this" object in the setTimeout function used the global highValue and constantVal variables, because the reference to "this" in the setTimeout function refers to the global window object, not to the myObj object as we might expect.
because this inside setTimeout is referring to global window context. Create a local variable, often named 'self', in the correct scope instead.
var highValue = 200;
var constantVal = 2;
var myObj = {
highValue: 20,
constantVal: 5,
calculateIt: function () {
var self = this;
setTimeout (function () {
console.log(self.constantVal * self.highValue);
}, 2000);
}
}
myObj.calculateIt(); // 400

How the JavaScript this keyword works?

I have been doing some JavaScript development and I encountered this problem. Consider the following code
var obj = {};
obj.bind = function () {
console.info(this);
};
obj.bind();
I'm running the code on the FireBug JavaScript console. The expected result is that this displays a reference to the object in the console.
It actually displays undefined.
But, when I make this change to my code
var obj = {};
obj.bind = function () {
this.x = 'x';
console.info(this);
};
obj.bind();
Now the console displays the expected value of this, which is a reference to the obj object.
Why does this happen?
undefined is the return value of the function, which you'll get because you're not returning a value explicitly.
In both Chrome and Firebug, it correctly displays the Object in the console before the return value undefined.
So if you do:
var obj = {};
obj.bind = function () {
console.info(this);
return "foo";
};
obj.bind();
...you should see something like:
Object { }
"foo"
If Firebug is not displaying the Object when it is empty, you may need to check to make sure you're using the most current version.
In your example, "this" should be obj, just as some commenters pointed out. Here are the details that explain why --
In Javascript, the value of "this" changes depending on how you call the function:
When a function is stored as a property on an object, and you invoke that function by calling obj.foo(), "this" will be obj.
EX:
var obj = {
x: 1,
increment: function() {
this.x = this.x + 1;
};
obj.increment(); // Makes "this" be obj
When you invoke a function using syntax that does not refer to any owning object, "this" will be the global environment.
EX:
function someFunc(a, b) {
return a + b; // If you were to refer to "this" here, it would be the global env.
}
someFunc(5, 6);
When you invoke a function as if it were a constructor by using the new operator, a new object will be instantiated for you, and "this" will point to that new object.
EX:
function SomeConstructor() {
this.x = 42; // under the hood, a new object was instantiated for you, and "this" was set to it.
}
var result = new SomeConstructor(); // note the "new" keyword
// result will be { x:42 }
When you use call() or apply(), you can control what "this" is.
(No example here since it's fairly far from your question. Look up docs for apply() or call() for an example.)

Categories