Some common javascript mistakes
Tags: javascript, productivity, node
Published: 2020-07-18 00:02:25


{% youtube xHecGK5QmPo %}

# Promise

This code seems "async" but it's not.
{% runkit %}
function myPromise() {
  return new Promise((resolve, reject) => {
    let i = 0;
    while (i < 1000000000) {
      i++;
    }
    resolve();
  })
}

console.log('start');
myPromise();
console.log('end');
{% endrunkit %}

What's going on here?. The answer is easy, the `promise` cannot be resolved until the while loop is ends.

To solve this we can do this.

{% runkit %}
function myPromise2() {
  return Promise.resolve().then(() => {
    let i = 0;
    while (i < 1000000000) {
      i++;
    }
  });
}

console.log('start');
myPromise2();
console.log('end');
{% endrunkit %}

Now this is `async` because our code is inside `Promise.resolve()`. Try to run this now.

# Reference copy
Sure you know (Spread Operator). This operator we used to do several operations like assigning properties or values, not copying object reference.

{% runkit %}
const arr1 = ['php', 'go', 'ruby'];
// wrong
const arr2 = arr1;

arr2.push('java');

console.log('arr1', arr1);
console.log('arr2', arr2);
{% endrunkit %}

Well we need use spread operator to fix this.

{% runkit %}
const arr1 = ['php', 'go', 'ruby'];
const arr2 = [...arr1, 'java'];

console.log('arr1', arr1);
console.log('arr2', arr2);
{% endrunkit %}

Other example.

{% runkit %}
const arr1 = [
  {id: 1, name: 'php'},
  {id: 2, name: 'ruby'},
];
const arr2 = [...arr1];

// but it doesn't copy the array reference but it does copy the object
console.log('arr1', arr1);
console.log('arr2', arr2);
 
const [obj] = arr2;
obj.id = 300000;
obj.name = 'OHHH';

console.log('arr1', arr1);
console.log('arr2', arr2);

{% endrunkit %}

We saw that spread operator doesn't work. Why?. Well spread operator works but only the first level, To solve this, we need to iterate each element of the array and apply the spread operator.

{% runkit %}
const arr1 = [
  {id: 1, name: 'php'},
  {id: 2, name: 'ruby'},
];
const arr2 = arr1.map((obj) => ({...obj}));

console.log('arr1', arr1);
console.log('arr2', arr2);

const [obj] = arr2;
obj.id = 300000;
obj.name = 'OHHH';

console.log('arr1', arr1);
console.log('arr2', arr2);

{% endrunkit %}

We used the funcion `map`, this function returns a new array, so it doesn't copy the array reference and apply spread operator to each object inside of the array. But we imagine that it has a more complicated object.

{% runkit %}
const arr1 = [
  {
     id: 1,
     name: 'php',
     moreProperties: {
       years: [2000,2001,2002],
       info: {
         title: 'Title',
         desc: 'Desc',
       },
     },
  },
  {
     id: 2,
     name: 'ruby',
     moreProperties: {
       years: [2020],
       info: {
         title: 'Title 2',
         desc: 'Desc 2',
       },
     },
  },
];

const notCopy = arr1.map((obj) => {
   const moreProperties = {
     years: [...obj.moreProperties.years],
     info: {...obj.moreProperties.info},
   };

   return {...obj, moreProperties };
});

console.log(notCopy)
{% endrunkit %}

The example above works, but there are several ways to do it. We can use [lodash](https://lodash.com/docs/) for example or use this code.

{% runkit %}
const arr1 = [
  {
     id: 1,
     name: 'php',
     moreProperties: {
       years: [2000,2001,2002],
       info: {
         title: 'Title',
         desc: 'Desc',
       },
     },
  },
  {
     id: 2,
     name: 'ruby',
     moreProperties: {
       years: [2020],
       info: {
         title: 'Title 2',
         desc: 'Desc 2',
       },
     },
  },
];

console.log(JSON.parse(JSON.stringify(arr1)))
{% endrunkit %}

# Comparation
A typical mistake, for example, is something that this.

{% runkit %}
const a = null;
const b = [];
const c = {};
const d = 1;
const e = NaN;

console.log('null and [] is: ' + (typeof a === typeof b).toString());
console.log('[] and {} is: ' + (typeof b === typeof c).toString());
console.log('1 and NaN is: ' + (typeof d === typeof e).toString());

{% endrunkit %}

Well I hope this can help you. If you are interested in knowing more you can see this repository [https://github.com/denysdovhan/wtfjs
](https://github.com/denysdovhan/wtfjs
)