Ever read JavaScript (JS) code and feel like you almost don’t understand what it does? This code uses a lot of JS tricks, right? Fairly arbitrary naming and programming style? These are symptoms of bad programming habits.

In this article, I will outline five common programming bad habits in JS. It is important that I present what I believe to be practical suggestions as to how to correct these bad habits.

JavaScript is a loosely typed programming language. If used properly, this is to our advantage as it provides a great deal of flexibility.

Most operators + – * / ==(but not ===) implicitly convert operands of different types. Statement if (condition) {… },(while(condition) {… } implicitly converts a condition to a Boolean value.

The following example relies on implicit conversions of types. I bet you’re confused:

console.log("2" + "1"); / / = >"21"
console.log("2" - "1");  // => 1

console.log(' '= = 0); / / = >true

console.log(true= = []); // ->false
console.log(true= =! []); // ->false
Copy the code

Relying too much on implicit type conversions is a bad habit. First, it makes your code less stable in the edge case. Second, it increases the chance of bugs that are difficult to reproduce and fix.

Now let’s use a function that gets 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'

Copy the code

GetProp () reads the value of the name property, which is ‘Batman’.

So what if we try to access the isVillian property:

console.log(getProp(hero, 'isVillian', true)); // => true

This is a mistake. GetProp () returns true even if hero’s property isVillian is false.

This is because validation of the property’s existence depends on if (! object[propertyName]) {… } Implicitly converted Boolean values.

These errors are hard to spot, and to fix the function, specify the type of the validation 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

Copy the code

Object [propertyName] === undefined exactly verifies whether the property is undefined.

Do you have any other ways to verify that properties exist in objects? If so, please leave them in the comment section below!

Side note: IN part 4 (here a hyperlink is needed to skip to part 4) I suggested avoiding undefined directly. Therefore, the above solution can be further improved with the operator in:

function getPropFixedBetter(object, propertyName, defaultValue) {
   if(! (propertyNamein object)) {
     return defaultValue;
   }
   return object[propertyName];
}
Copy the code

My advice: Avoid implicit type conversions whenever possible. Instead, make sure that variables and function parameters always have the same type, using explicit type conversions if necessary.

Here’s what you should do:

Always use the strict equality operator === for comparison

Do not use the loose equality operator ==

The addition operator operand1 + operand2: Both operands should be numbers or strings

Arithmetic operator – * / % ** : Both operands should be numbers

if (condition) {… }, while (condition) {… } and so on. Condition must be a Boolean value

You might think that this would require more code… Indeed! But with explicit methods, we can control the behavior of our code. In addition, explicit type conversions enhance readability.

The interesting thing about JS, an early JavaScript trick, is that its creators didn’t expect the language to become so popular. The complexity of applications built on JS is growing faster than the language. This situation forces developers to use JS tricks and workarounds just to make things work.

A typical example is to check whether an array contains an element. I would never use array.indexof (item)! == -1 to check.

ECMAScript 2015 and later are much more powerful, and many tricks can be safely refactored using new language features.

In the new ES2015 you can use array.includes(item) instead of array.indexof (item)! = = 1.

You can follow my list of refactorings to remove old tricks from your JS code.

Before ES2015, JS variables were in function scope, so you might get used to declaring all variables in function scope.

Let’s 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;
}
Copy the code

The variables index, item, and length are in the scope of the function. But these variables affect the function scope because they are only needed in the for() block scope.

Since block-scoped lets and const have been introduced, we should limit the lifetime of variables as much as possible.

Let’s clean up the function scope:


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;
}
Copy the code

The variables index and item are limited to the scope of the for() loop block. Length is moved closer to where it is used.

The refactored code is easier to understand because variables are not scattered throughout the function scope; they exist near where they are used.

Define variables in the block scope used:

If block scope

// Bad
let message;
// ...
if (notFound) {
  message = 'Item not found';
  // Use `message`
}
Copy the code
// Good
if (notFound) {
  const message = 'Item not found';
  // Use `message`
}

Copy the code

For block scope

// Bad
let item;
for (item of array) {
  // Use `item`
}
Copy the code
// Good
for (const item of array) {
  // Use `item`
}

Copy the code

4. Avoid undefined and NULL variables that are not assigned a value are assigned undefined by default. For example,

let count;
console.log(count); // => undefined

const hero = {
  name: 'Batman'
};
console.log(hero.city); // => undefined

Copy the code

The count variable is defined but not initialized with a value. JS implicitly assigns it undefined.

Undefined is also returned when we access the nonexistent property hero.city.

Why is using undefined a bad habit? Because when we compare undefined, we’re actually dealing with variables that are in an uninitialized state.

Variables, object properties, and arrays must be initialized with values before they can be used

JS provides many ways to avoid comparisons with undefined.

Determines whether the attribute exists

// Bad
const object = {
  prop: 'value'
};
if (object.nonExistingProp === undefined) {
  // ...
}
Copy the code
// Good
const object = {
  prop: 'value'
};
if ('nonExistingProp' in object) {
  // ...
}
Copy the code

The default property of the object


// Bad
function foo(options) {
  if (object.optionalProp1 === undefined) {
    object.optionalProp1 = 'Default value 1';
  }
  // ...
}
Copy the code
// Good
function foo(options) {
  const defaultProps = {
    optionalProp1: 'Default value 1'}; options = { ... defaultProps, ... options }; / /... }Copy the code

Default function parameters

// Bad
function foo(param1, param2) {
  if (param2 === undefined) {
    param2 = 'Some default value';
  }
  // ...
}
Copy the code
// Good
function foo(param1, param2 = 'Some default value'{/ /... }Copy the code

Null is an indicator of a missing object. We should avoid returning NULL from functions, especially when calling functions with NULL as an argument.

Once NULL is in the call stack, we must check for its presence in every function that might access null, and we can inadvertently make an error.


function bar(something) {
  if (something) {
    return foo({ value: 'Some value' });
  } else {
    returnfoo(null); }}function foo(options) {
  let value = null;
  if(options ! == null) { value = options.value; / /... }return value;
}
Copy the code

Try to write code that doesn’t involve NULL. You can use try /catch mechanisms instead, default objects. Tony Hoare, the inventor of Algol, once said, “I call it my billion-dollar mistake… […]. I designed the first comprehensive type system for an object-oriented language. […]. But I can’t resist putting in null references because it’s so easy to implement. This has led to countless errors, bugs, and system crashes that have probably cost a billion dollars over the last four decades.”

“The Worst Mistakes in Computer Science” delves into why NULL destroys code quality.

5. Don’t use arbitrary coding styles. What could be more intimidating about implementing a standard than reading code with a random coding style? You never know what will happen! What if the code base contains many developers with different coding styles? It’s like a wall of characters.

Some examples of useful coding styles: Airbnb JS Style Guide Google JS Style Guide To be honest, I’m lazy. I can “forget” how to style my design code when I’m facing a dead end or preparing to commit before I go home.

My lazy self always said, “Here we go, update it later,” but “later” meant never.

So HERE I recommend using ESLint to standardize the coding style. Install ESLint to configure ESLint to set up a pre-commit hook using the coding style that best suits you, and run ESLint validation before committing.

6. Conclusion Writing high quality and clean code requires discipline, and we overcome coding bad habits.

JS is a free programming language with great flexibility. But we have to be careful what features we use. My advice here is to avoid using implicit type conversions of undefined and NULL.

These days programming languages are evolving quite rapidly. Find complex code and use the latest JS features to refactor and simplify. A consistent coding style throughout the code base benefits readability. Good programming skills are always a win-win solution.

That’s all for today’s sharing. I hope this article can help you!

After watching

Click like, so that more people can see this content (collection does not click like, are playing rogue -_-) pay attention to the public number “new front-end community”, enjoy the first article experience! Focus on conquering one front-end technical difficulty every week.