Stack Overflow Asked by Lucas Antunes on January 3, 2022
I have the following snippet of code:
init: function () {
var $mainSection = $('.main-section'),
cardId = '',
cardTitle = '',
cardSelected = '';
$('.large-card', $mainSection).each(function () {
cardId = getCardId(this);
cardTitle = $('.card-title', this).text().trim();
cardsModel[cardId] = { title: cardTitle, id: cardId, selected: false };
$('.checkbox', this).on('click', function () {
cardSelected = cardsModel[cardId].selected;
cardsModel[cardId].selected = !cardSelected;
});
});
},
getCardId: function (card) {
var prop, value;
for (prop in card.classList) {
if (card.classList.hasOwnProperty(prop)) {
value = card.classList[prop];
if (value.startsWith('product-id--')) {
return value.replace('product-id--', '');
}
}
}
},
cardsModel: []
I’m used to write all var
definitions on the top of my functions, whenever possible, as suggested by some colleague that told me this is better for minifiers and such.
The thing is, if I don’t use var
in line 8, for instance, the click
events on each .checkbox
element always get cardId
as the last .large-card
ID. So, hypothetically, if I have 5 cards with IDs 1, 2, 3, 4 and 5, if I click on any of their checkboxes, it’ll always update the ID 5.
If I use var cardId = getCardId(this);
, however, the code works as expected.
I may be missing something pretty basic here, but can someone please explain me why this happens?
This honestly makes me fear to write var
definitions like this again lol.
Yes, I searched for similar questions and, if this is a dupe, I probably didn’t know how to search for it, thus I apologize if it is.
Thank you!
As War10ck mentioned above, it's about scope and hoisting. And this isn't just tied to Javascript, but global and local scopes exists in most programming languages. There might be multiple solutions to fix this, but I myself usually initialize the variables I know I'll use in multiple local scopes in the top of the file, like this for example:
let exampleVariable;
But be careful. You should only use this if you really need to, because too many global variables can make your code messy real fast. Also, you should try not using var, since it also can bring some "problems" in your code with your global scope and instead use ES6's let & const.
Answered by Dippe on January 3, 2022
This has to do with the way JavaScript handles scope and hoisting. This page has a nice summary explaining these concepts:
JavaScript has two scopes – global and local. Any variable declared outside of a function belongs to the global scope, and is therefore accessible from anywhere in your code. Each function has its own scope, and any variable declared within that function is only accessible from that function and any nested functions.
Note: Emphasis above is mine. As of EcmaScript 2015, this is not entirely correct. The use of the let
operator allows for block scope as well. More on that below.
In your example above, you first decalre the cardId
variable in the init
function. This means that the scope of cardId
is local to the init
function and any nested functions. Since you don't re-declare cardId
in the .each()
callback, the JavaScript engine will climb the scope chain to see if it exists in another accessible scope or the global scope before creating it in the global scope if it does not already exist.
It's important to note that when assiging, the variable will be automatically created at the global scope level if not previously defined (except for maybe in strict mode, not sure about that). However, trying to reference an undefined
variable for an operation, such as a comparison will throw a ReferenceError
noting that the variable is not defined.
Finally, note that unlike in some other languages, var
operates within function
scope, not block
scope. To utilize block
scope in JavaScript, you can use the new let
operator. Here is a nice article describing the scopes and proper uses of var
and let
in JavaScript.
Answered by War10ck on January 3, 2022
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP