👍11 Bad Ways to Write JavaScript

👍11 Bad Ways to Write JavaScript

Aug 31, 2023
Chia sẻ
Sưu tầm
JavaScript is an integral part of modern web development, but it has some pitfalls to be aware of. In this article, we’ll introduce ten common ways to write JavaScript to help you avoid some common mistakes and pitfalls.

1. Implicit type conversion

Implicit type conversion refers to JavaScript automatically converting one data type to another data type at runtime. For example, when you concatenate two strings using the plus sign, JavaScript automatically converts them to strings and concatenates them. While this may seem convenient, it can often cause problems, especially for inexperienced developers.
let result = "3" + 4 + 5 ; // '345' let result2 = 3 + 4 + "5" ; // '75'
In the above code, the output result of the first line is the string ‘345’, and the output result of the second line is the string ‘75’. This is because JavaScript converts the number to a string when processing the plus sign, and then performs the concatenation operation. Therefore, when you use the plus sign to concatenate numbers and strings, care must be taken to avoid unexpected behavior.

2. Use var to declare variables

Before ES6, the only way to declare variables in JavaScript was with var keywords. But var there are some scope problems, which are easy to cause variable pollution and other problems. Therefore, it is best to use let or const to declare variables, they are block-level scope.
function example () { var foo = "bar" ; if ( true ) { var foo = "baz" ; console . log (foo); // 'baz' } console . log (foo); // 'baz' }
function example2 () { let foo = "bar" ; if ( true ) { let foo = "baz" ; console . log (foo);// 'baz' } console . log (foo); // 'bar' } example (); example2 ();
In the above code, when the first example var declares variables, the inner one foo overrides the outer one foo, resulting in the output of both being the string 'baz'. In the second example let , after declaring variables, the inner ones foo only exist in the inner scope and will not affect the outer ones foo.
Another example is the following question that is often encountered in interviews:
for ( var i = 0 ; i < 5 ; i ++ ) { setTimeout ( function () { console . log (i); }, 1000 ); } // output 5, 5, 5, 5, 5
This is because the callback functions of setTimeout are executed asynchronously, and when they are executed, the value of i has become 5, and let or closure can be used to solve this problem.

3. Frequent operation of DOM

Manipulating the DOM directly is very inefficient because doing so causes the page to re-render repeatedly, reducing performance and user experience. Instead, a more efficient way should be used to operate the DOM, such as reducing the number of DOM queries, using virtual DOM technology, and so on.
// not recommended document.getElementById('my-button').addEventListener('click', function() { document.getElementById('my-text').innerText = 'Hello, world!'; }); // recommended const myText = document.getElementById('my-text'); document.getElementById('my-button').addEventListener('click', function() { myText.innerText = 'Hello, world!'; });
In the code above, the first example re-queries the DOM and updates it every time the button is clicked, while the second example only queries the DOM once and then updates the element’s text content.

4. Modify the prototype object

Modifying prototype objects can cause some unexpected problems. For example:
Array.prototype.sum = function() { return this.reduce(function(a, b) { return a + b; }, 0); }; var arr = [1, 2, 3]; console.log(arr.sum()); // 6
While the above code works fine, it may have unintended effects in other parts. To avoid this problem, we should try to avoid modifying the prototype object.

5. Using global variables

Global variables are a common type of variable in JavaScript, but they can cause naming conflicts and other problems. Therefore, it is best to avoid global variables and organize your code in a modular fashion.
// not recommended function foo() { globalVar = "bar"; } // recommended const myModule = (function() { const localVar = "baz"; function foo() { // do something with localVar } return { foo: foo }; })();
In the above code, the first example uses a global variable globalVar, which may be overwritten by other code. The second example uses IIFE (Immediately Invoked Function Expressions) to create a module in which variables are only visible inside the module and will not affect other code.

6. Ignore semicolons

JavaScript allows semicolons to be omitted at the end of statements, but this tends to lead to some errors, especially when the code is minified or merged. Therefore, it is recommended to always end statements with a semicolon to avoid potential problems.
// not recommended let x = 1 let y = 2 // recommended let x = 1 ; let y = 2 ;
In the code above, the first example omits the semicolon, which may lead to some unexpected behavior. The second example explicitly adds a semicolon, which is more standardized.

7. Using a for-in loop

for-in A loop is a way to iterate over the properties of an object, but it has some drawbacks. Because it not only traverses the properties of the object itself, but also traverses the properties inherited from the prototype chain, which may lead to some unexpected results.
const person = { name : "Alice" , age : 30 , gender : "female" }; // not recommended for ( const key in person) { console . log (person[key]); } // recommended Object . keys (person). forEach (key => console . log (person[key]));
In the above code, the first example uses for-in a loop to traverse object properties, while the second example uses Object.keys() a method to obtain the property name of the object itself, and cooperates with forEach() the method to traverse.

8. Compare NaN

NaN Is a special type of numeric value, said Not-a-Number (not a number). However, since NaN it is not equal to any value, it is necessary to use a function to judge when comparing isNaN() .
// not recommended if (x == NaN) { // do something } // recommended if (isNaN(x)) { // do something }
In the above code, the first example mistakenly uses the equality operator for comparison NaN, while the second example uses isNaN() a function for judgment.

9. Using eval()

eval() is a way to execute string code, but it tends to cause security issues and performance issues. Therefore, it is best avoided in production environments eval().
// not recommended eval("console.log('Hello, world!')"); // recommended const code = "console.log('Hello, world!')"; Function(code)();
In the above code, the first example uses eval() a function to execute string code, while the second example uses Function() a function to create a new function and execute it.

10. Ignore Error Handling

Ignoring error handling is a common mistake because it can lead to code crashes. For example:
try { // some code } catch (e) {}
Although this code that throws the exception may not matter, it can cause problems during development or runtime if the exception is not handled properly.
To avoid this problem, we should always handle exceptions properly, for example by logging or displaying user-friendly error messages.

11. Forgot to bind this when passing function as parameter

When passing a function as a parameter, you need to pay attention to the value of binding this. For example:
const obj = { name : 'Alice' , greet : function () { console . log ( 'Hello, ' + this .name); } }; setTimeout (obj. greet, 1000 ); // Hello, undefined
The correct way to write it should be to use the bind method:
const obj = { name : 'Alice' , greet : function () { console . log ( 'Hello, ' + this .name); } }; setTimeout (obj. greet . bind (obj), 1000 ); // Hello , Alice


JavaScript is an indispensable part of modern web development, it provides us with rich functions and flexibility, when writing JavaScript code, we should try to keep the code readable, concise and maintainable, in order to Build great web applications.