String doesn’t seem to be passed by value [duplicate] - javascript

This question already has answers here:
Access outside variable in loop from Javascript closure [duplicate]
(5 answers)
Closed 8 years ago.
I use the following function to bind all members of a certain class to a function that changes the current page. Heres the function:
function _bind_menu_items() {
var menuItems = fja.getElementsByClass("menuItem"),
index,
elementID,
divIdToBind;
for (index in menuItems) {
elementID = menuItems[index].id;
divIdToBind = elementID.replace("Item", "");
menuItems[index].onclick = function() {
fja.menu.changeActivePage(divIdToBind);
};
}
}
I’ve checked that everything works as expected down to the actual assignment of the onclick property. The error I’m getting is that every div belonging to the menuItem class seems to call the same onclick function... as if the divIdToBind string is the exact same for every onclick that is assigned... How can I fix this?

Number one mistake for Javascript beginners. you're missing that the anonymous functions which gets bound to your onclick handler, closes over its parent context. Since all closures from the same parent context share the same scope chain, all of this functions will reference the last value which gets passed into divIdToBind.
To solve that issue, the most common workaround is to create another function(-context):
menuItems[index].onclick = (function(id) {
return function() {
fja.menu.changeActivePage(id);
};
}(divIdToBind));
Now we do create another function which gets executed immediately. We pass it in the value from divIdToBind and all it does is to return another function (just to create a new context)

Related

How to access value returned from a function expression? [duplicate]

This question already has answers here:
javascript named function expressions - scope accessibility [duplicate]
(4 answers)
Closed 2 years ago.
I'm trying to return and access the value of a dynamic select from onchange event. I know how to work with function declarations but function expressions are unclear to me. A little help would be appreciated.
js
//create select
var select = document.createElement('select');
select.setAttribute('id','select_month');
//onchange
select.onchange = function changeMonth(selectedmonth){
selectedmonth = this.value;//works well here
return selectedmonth;
};
var selectedmonth = changeMonth();//undefined
changeMonth is a variable that is scoped only to the function itself, and is therefore not available to the rest of the script.
Even if it was available, then realise that when that function is called by the DOM (when the event fires), it calls it with this bound to the DOM element. When you call it explicitly in your code, you should do the same.
The good thing is that the reference to the function is available as select.onchange, so use that. That way you solve both issues at the same time:
var selectedmonth = select.onchange(select);

Get function's this binding [duplicate]

This question already has an answer here:
How to inspect a JavaScript Bound Function
(1 answer)
Closed 2 years ago.
Given a function,
function main() {
// some logic
}
Lets assume the function main is bind with const obj = { name: "John Doe" }
like const fn = main.bind(obj);
Now the question is, Is there a way to get the fn function binding?
Note: i know binding can be accessed using the this keyword inside the main function but is there any way to access this value outside the context. is there any magic (hypothetical) method like fn.getContext().
Thank you for your time.
No there is not. While the new function object has an internal [[BoundThis]] slot, that slot is not accessible via a user-facing API.

Using 'this' in javascript function attached to object property [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 3 years ago.
Edit:
The question referred to as the duplicate doesn't really answer why arrow functions shouldn't be used to access a non-lexical this. It just answers that arrow functions automatically bind this. My situation is that using an arrow function rather than a normal function cause me to lose the correct reference of this. If you need this outside of the current scope, use a normal function.
I've searched around for a solution to my problem with no luck. Even if I was pointed in the right direction as to what I needed to do would be awesome! My problem essentially is that this.Favkey is undefined here:
const setFavorite = val => {
console.log(this);
this.Favorite = val;
AsyncStorage.setItem(this.Favkey, JSON.stringify(val));
};
This function is getting assigned to a particular object like so:
for (const obj of objArray) {
obj.Favkey = `c${obj['-id=']}`;
obj.Favorite = await getFavorite(obj.Favkey);
obj.SetFavorite = setFavorite;
}
And then I am calling this later on a button:
onPress={val => props.myObj.SetFavorite(val)}
In the first block of code, I want this to be the specific obj that I am attempting to enclose the function on. But this.Favkey in setFavorite is undefined. What is printed out instead on console.log(this) is what I think is the whole prototype of Object. So I'm not quite sure what I'm doing wrong here.
Don't use an arrow function - it loses the binding to this which is what you're trying to access. Just use a normal function:
const setFavorite = function(val) {...};

Lexical `this` and Timeout [duplicate]

This question already has answers here:
How does the "this" keyword in Javascript act within an object literal? [duplicate]
(4 answers)
Closed 5 years ago.
Im reading through the YDKJS books and I thought I understood lexical this for the most part.
However there is a section with code that shows this:
var obj = {
id: "awesome",
cool: function coolFn() {
console.log( this.id );
}
};
var id = "not awesome";
obj.cool(); // awesome
setTimeout( obj.cool, 100 ); // not awesome
Ok so the first obj.cool() makes sense of course....but why is the setTimeout printing not awesome.....I mean it's still calling obj.cool() which this refers to it's own objects id?
Or does setTimeout get called as another function that calls obj.cool()? but even in that case (Which I tried calling obj.cool() inside another function that also had an id property and it still printed the right one......so why would the this change with setTimeout?
Since the OBJ.COOL function is passed by reference, you are not actually passing the context object with it. The function gets new invocation context and executes on the WINDOW object, which now has a property called ID which was defined earlier.

'this' is undefined in the next scope [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 6 years ago.
My problem is as simple as the title.. I have some code which makes an AJAX call. This code is similar to this (JSFiddle):
function Test() {
this.name = "U don't wanna know my name..";
}
Test.prototype.ajax = function() {
$.ajax("url/path", data, function() {
alert(this.name);
});
};
var test = new Test();
test.ajax();
In this case this is undefined. I could place the following code before the ajax call and use that in stead of this:
var diz = this;
I was wondering if there's another way of using this without creating a new variable for it.
In this case this is undefined.
this.name is undefined (assuming you meant that), because this is specific to a function's context. Inside that ajax's callback handler this no more belonged to Test, it belonged to that callback function.
was wondering if there's another way of using this without creating a
new variable for it.
I don't think that without saving the reference to parent's this (Test's this) you can access this that belonged to a more global scope from a function's scope.

Categories