Home > Article > Web Front-end > 5 bad habits in JS coding, how to avoid them?
Have you ever had that feeling when reading JavaScript code
You barely understand what the code does?
The code uses a lot of JavaScript tricks?
The naming and coding style are too casual?
These are all signs of bad coding habits.
In this article, I describe 5 common bad coding habits in JavaScript. Importantly, this article will give you some practical advice on how to get rid of these habits.
1. Don’t use implicit type conversion
JavaScript is a loosely typed language. This is a benefit if used correctly because it gives you flexibility.
Most operators - * / == (excluding ===) perform implicit conversions when handling operands of different types.
The statements if (condition) {...}, while (condition) {...} implicitly convert the condition into a Boolean value.
The following example relies on implicit type conversion, which can sometimes be confusing:
console.log("2" + "1"); // => "21" console.log("2" - "1"); // => 1 console.log('' == 0); // => true console.log(true == []); // -> false console.log(true == ![]); // -> false
Overreliance on implicit type conversion is a bad habit. First, it makes your code less stable in edge cases. Secondly, it increases the chance of introducing bugs that are difficult to reproduce and fix.
Now we implement a function to obtain object properties. If the attribute does not exist, the function returns a default value
function getProp(object, propertyName, defaultValue) { if (!object[propertyName]) { return defaultValue; } return object[propertyName]; } const hero = { name: 'Batman', isVillian: false }; console.log(getProp(hero, 'name', 'Unknown')); // => 'Batman'
getProp() reads the value of the name attribute, which is 'Batman'.
Then trying to access the isVillian property:
console.log(getProp(hero, 'isVillian', true)); // => true
This is an error. Even if hero's property isVillian is false, the function getProp() will return false true.
This is because the verification of the property's existence relies on the boolean implicitly converted by if(!object[propertyName]){...}.
These errors are difficult to find. To fix the function, explicitly verify the type of the value:
function getPropFixed(object, propertyName, defaultValue) { if (object[propertyName] === undefined) { return defaultValue; } return object[propertyName]; } const hero = { name: 'Batman', isVillian: false }; console.log(getPropFixed(hero, 'isVillian', true)); // => false
object[propertyName] === undefined Verify exactly whether the property is undefined.
It is recommended to avoid using undefined directly. Therefore, the above solution can be further improved:
function getPropFixedBetter(object, propertyName, defaultValue) { if (!(propertyName in object)) { return defaultValue; } return object[propertyName] }
Forgive the author's suggestion: do not use implicit type conversions as much as possible. Instead, make sure that variables and function parameters always have the same type, using explicit type conversions when necessary.
Best Practice List:
Always use strict equality operator === for comparisons
Do not use loose Equality operator==
Addition operator operand1 operand2: Both operands should be numbers or strings
Arithmetic operators - */%**: Both operands should be numbers
if (condition) {...}, while (condition) {...} and other statements: condition must Is a boolean value
You might say that this way requires writing more code... you would be right! But with explicit methods, you can control the behavior of your code. Additionally, explicitness improves readability.
2. Don’t use early JavaScript tricks
The interesting thing about JavaScript is that its creators didn’t I didn't expect this language to be so popular.
The complexity of applications built on JavaScript is evolving faster than the language. This situation forces developers to use JavaScript tricks and workarounds just to make things work properly.
A typical example is to check whether an array contains a certain element. I never like using array.indexOf(item)! == -1 to check.
ES6 and later are much more powerful, and many tricks can be safely refactored using new language features.
In ES6 you can use array.includes(item) instead of array.indexOf(item) !== -1
3. Don’t pollute the function scope
Before ES2015, you may have the habit of declaring all variables in function scope.
Let’s take a look at an example:
function someFunc(array) { var index, item, length = array.length; /* * Lots of code */ for (index = 0; index < length; index++) { item = array[index]; // Use `item` } return someResult; }
The variables index, item and length are within the function scope. But these variables affect function scope because they are only needed within the for() block scope.
By introducing let and const with block scope, the life cycle of variables should be limited as much as possible.
function someFunc(array) { /* * Lots of code */ const length = array.length; for (let index = 0; index < length; index++) { const item = array[index]; // Use `item` } return someResult; }
The index and item variables are restricted to the for() loop block scope. length has been moved closer to where it is used.
Refactored code is easier to understand because variables are not scattered throughout the function scope, they exist close to where they are used.
Define variables in the block scope used
if block scope
// 不好 let message; // ... if (notFound) { message = 'Item not found'; // Use `message` } // 好 if (notFound) { const message = 'Item not found'; // Use `message` } for 块作用域 // 不好 let item; for (item of array) { // Use `item` } // 好 for (const item of array) { // Use `item` }
4. Try to avoid undefined and null
Unassigned variables are assigned undefined by default. For example the
let count; console.log(count); // => undefined const hero = { name: 'Batman' }; console.log(hero.city); // => undefined
count variable is defined but has not been initialized with a value. JavaScript implicitly assigns it undefined.
When accessing the non-existent property hero.city, undefined will also be returned.
Why is it a bad habit to use undefined directly? Because when comparing to undefined, you are dealing with a variable in an uninitialized state.
Variables, object properties and arrays must be initialized with values before use
JS 提供了很多避免与undefined进行比较方式。
判断属性是否存在
// 不好 const object = { prop: 'value' }; if (object.nonExistingProp === undefined) { // ... } // 好 const object = { prop: 'value' }; if ('nonExistingProp' in object) { // ... }
对象的默认属性
// 不好 function foo(options) { if (object.optionalProp1 === undefined) { object.optionalProp1 = 'Default value 1'; } // ... } // 好 function foo(options) { const defaultProps = { optionalProp1: 'Default value 1' }; options = { ...defaultProps, ...options } }
默认函数参数
// 不好 function foo(param1, param2) { if (param2 === undefined) { param2 = 'Some default value'; } // ... } // 好 function foo(param1, param2 = 'Some default value') { // ... }
null是一个缺失对象的指示符。应该尽量避免从函数返回 null,特别是使用null作为参数调用函数。
一旦null出现在调用堆栈中,就必须在每个可能访问null的函数中检查它的存在,这很容易出错。
function bar(something) { if (something) { return foo({ value: 'Some value' }); } else { return foo(null); } } function foo(options) { let value = null; if (options !== null) { value = options.value; // ... } return value; }
尝试编写不涉及null的代码。 可替代方法是try /catch机制,默认对象的使用。
5. 不要使用随意的编码风格,执行一个标准
有什么比阅读具有随机编码风格的代码更令人生畏的事情? 你永远不知道会发生什么!
如果代码库包含许多开发人员的不同编码风格,该怎么办?,这种就像各色人物涂鸦墙。
整个团队和应用程序代码库都需要相同的编码风格,它提高了代码的可读性。
一些有用的编码风格的例子:
Airbnb JS 风格指南
谷歌 JS 风格指南
老实说,当我在回家前准备提交时,我可能会忘记设计代码的样式。
我自己总说:保持代码不变,以后再更新它,但是“以后”意味着永远不会。
这里建议使用 eslint 来规范编码风格。
安装eslint
使用最适合自己的编码风格配置 eslint
设置一个预提交钩子,在提交之前运行eslint验证。
总结
编写高质量和干净的代码需要纪律,克服不好的编码习惯。
JavaScript是一种宽容的语言,具有很大的灵活性。但是你必须注意你所使用的特性。这里建议是避免使用隐式类型转换,undefined 和 null 。
现在这种语言发展得相当快。找出复杂的代码,并使用最新 JS 特性来重构。
整个代码库的一致编码风格有益于可读性。良好的编程技能总是一个双赢的解决方案。
推荐教程:《JS教程》
The above is the detailed content of 5 bad habits in JS coding, how to avoid them?. For more information, please follow other related articles on the PHP Chinese website!