š11 Bad Ways to Write JavaScript
date
Aug 31, 2023
slug
11-bad-ways-to-write-javascript
status
Published
tags
Chia sįŗ»
Study
SĘ°u tįŗ§m
summary
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.
type
Post
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
epilogue
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.