Why JavaScript Breaks Your Brain, But Shouldn't Break Your Career
\n\nJavaScript is both the friendliest and the most treacherous programming language. On one hand, you write console.log('Hello') — and the result instantly appears in the browser. On the other hand, the same code can suddenly output undefined, NaN, or something worse, and you'll spend an hour looking for a bug hiding in a single line.
At pythonlib.ru, we know how important it is to learn from others' mistakes. In this article, we'll break down 5 typical mistakes beginners make in JavaScript that turn your code into a pumpkin. And most importantly — we'll show you how to fix them. Let's go!
\n\nMistake #1: The Magical 'var' and Misunderstanding Scope
\n\nMany beginner developers learning JavaScript use var to declare variables. This is a legacy of the old ES5 standard that still lives on in decade-old textbooks. But var is like an old car without airbags: you can drive it, but at the first accident (read: bug), you'll be in serious trouble.
What's the problem?
\nvar has function scope, not block scope. This means a variable declared inside an if or for block is accessible outside of it.
// Example: Mistake with var\nfunction testVar() {\n if (true) {\n var x = 10;\n }\n console.log(x); // 10 — works, even though x was declared inside if\n}\n\ntestVar();\n\nNow imagine you have 1000 lines of code in your project. You declared var i in a loop, and later accidentally use the same variable — you get a bug that's impossible to track down.
How to do it right?
\nUse let and const. They have block scope and behave predictably.
// Correct: let and const\nfunction testLet() {\n if (true) {\n let y = 20;\n const z = 30;\n }\n console.log(y); // ReferenceError: y is not defined\n}\n\ntestLet();\n\nTip: always use const by default. Only if the variable needs to be reassigned should you use let. Leave var in the past, like floppy disks.
Mistake #2: The Forgotten 'this' Keyword — Losing Context
\n\nThe this keyword in JavaScript is like a surprise in a chocolate egg: you never know what you'll get. Beginners often think that this always points to the current object. But that's not the case. this depends on how the function is called, not where it's declared.
Classic example: losing context in a callback
\n\nconst user = {\n name: 'Anna',\n greet: function() {\n console.log('Hello, ' + this.name);\n }\n};\n\nuser.greet(); // Hello, Anna — works\n\nsetTimeout(user.greet, 1000); // Hello, undefined — context lost!\n\nWhy is that? Because setTimeout calls the function as a regular function, not as a method of the object. In this case, this points to the global object (in the browser — window), which has no name property.
How to fix it?
\nThree ways:
\n- \n
- Arrow function — it doesn't create its own
this, but takes it from the outer context. \n - The
.bind()method — permanently binds the context. \n - Storing a reference to
this(old way, better not to use). \n
// Fix: arrow function\nconst user = {\n name: 'Anna',\n greet: function() {\n console.log('Hello, ' + this.name);\n }\n};\n\nsetTimeout(() => user.greet(), 1000); // Hello, Anna\n\n// Or with bind\nsetTimeout(user.greet.bind(user), 1000); // Hello, Anna\n\n