Sort, & find out duplicates and missing elements in an array this code is for return duplicates after sorted them, and also to
  return the missed value between the limits of the given array, it's
  executed correctly, but i need to optimize it so it excecute in less
  time than it execute can any one help?




function findDupsMiss(arr) {
    // your code here
    var noDuplicates = [];
    var missedNum;
    var duplicates = [];
    var sortedDuplicates =[]

arr.forEach((el, i) =&gt; {
 if(noDuplicates.includes(el) == false){
   noDuplicates.push(el)
 }
})
var sortedArr = noDuplicates.sort((a,b) =&gt; a-b);
for(var i=0 ; i&lt;sortedArr.length -1 ; i++){
  if((sortedArr[i]+1) !== sortedArr[i+1]){
    missedNum = sortedArr[i] + 1
   }
}
arr.forEach( el =&gt; {
  if(arr.indexOf(el) != arr.lastIndexOf(el)){
    duplicates.push(el)
  }
})
duplicates.forEach(el =&gt; {
  if(sortedDuplicates.includes(el) == false){
   sortedDuplicates.push(el)
 }
})


var lastdup = sortedDuplicates.sort((a,b) =&gt; a-b);
return [missedNum , lastdup]

}
findDupsMiss([10,9,8,9,6,1,2,4,3,2,5,5,3])
On the small 13 element array your implementation appears to be fairly performant, but since you request a "faster" implementation I took a stab at one myself.

Implementation

In this implementation I wanted to remove the multiple loops and use a data structure that lent itself to faster lookups, so I used plain javascript objects as maps. I also defined each array function callback outside where it'd be used to only instantiate a single copy.

function findDupsMiss2(arr) {
  const processedNumbers = {};
  const duplicates = {};
  const noDuplicates = {};

  const checkDupOrNot = (el, i) =&gt; {
    if (processedNumbers[el]) {
      duplicates[el] = el;
      delete noDuplicates[el];
    } else {
      noDuplicates[el] = el;
    }
    processedNumbers[el] = el;
  };

  arr.forEach(checkDupOrNot);

  const missedReduceFn = (missed, el, i, arr) =&gt;
    el + 1 !== arr[i + 1] ? el : missed;
  const missed = [
    ...Array(
      processedNumbers[Object.values(processedNumbers).length - 1]
    ).keys()
  ].reduce(missedReduceFn, null);

  return [missed, Object.values(duplicates)];
}


Testing

This is the function I defined to measure how performant a function is:

const measurePerf = (fn, data, runs = 1000000) =&gt;
  [...Array(runs).keys()]
    .map(() =&gt; {
      const start = performance.now();
      fn(data);
      const end = performance.now();
      return end - start;
    })
    .reduce((total, current) =&gt; total + current) / runs;


This takes a function and measures how long it takes to execute, sums the total time then divides by the # of runs to get an average execution time.

Used as such 

measurePerf(findDupsMiss, data); // uses default 1 million iterations
measurePerf(findDupsMiss, data, 1000);


Initial Results

Using the default 1-million iteration performance measure

findDupsMiss1
[7, Array[4]]
0: 7
1: Array[4]
0: 2
1: 3
2: 5
3: 9
0.0021040050006413367

findDupsMiss2
[7, Array[4]]
0: 7
1: Array[4]
0: 2
1: 3
2: 5
3: 9
0.0023690749967063313


At first this may seem like your code is already faster (or my implementation is slower), but this isn't the entire story.

If we analyze the Big-O complexity of your implementation we find it is O(n^2). Of the outer loops (3x O(n) forEach loops and 2x O(nLog_n) sorts) each of the forEach loops has an additional O(n) search loop to find either an index or if an element is already included, bumping the Big-O to O(n^2).

The other implementation has also 4x loops (1x forEach, 1x array spread, 1x array reduce, 1x object.values), but has no inner loops, each loop uses an O(1) lookup in a map, so has an O(n) complexity.


  But where is the sort?


When using an object as a map with number-like keys, they are inserted in numerical order, so we get "sorting" for free. (in reality there is probably some minimal search though).

Further Results &amp; Extended Examination


  What does this Big-O O(n^2) vs O(n) mean?


This has to do with how much work there is to do based upon input size. When an algorithm's Big-O complexity is O(n) then when the input size doubles the output should roughly double, i.e. something like 2n (hand wavey), whereas when an algorithm's Big-O complexity is O(n^2) then the output size something more like 4n.

Here's a rough table of output. Because of performance I had to drop the test performance iterations to 100 (versus10^6), but figured 100 runs is still enough to gather enough data for decent comparisons.

TBH the average is less relevant here as this table is more to illustrate the ratio between the two algorithms, with a secondary comparison in parenthesis to highlight the ratio of output from the previous iteration



const measurePerf = (fn, data, runs = 1000000) =&gt;
  [...Array(runs).keys()]
    .map(() =&gt; {
      const start = performance.now();
      fn(data);
      const end = performance.now();
      return end - start;
    })
    .reduce((total, current) =&gt; total + current) /runs;

function findDupsMiss1(arr) {
  // your code here
  var noDuplicates = [];
  var missedNum;
  var duplicates = [];
  var sortedDuplicates = [];

  arr.forEach((el, i) =&gt; {
    if (noDuplicates.includes(el) == false) {
      noDuplicates.push(el);
    }
  });
  var sortedArr = noDuplicates.sort((a, b) =&gt; a - b);
  for (var i = 0; i &lt; sortedArr.length - 1; i++) {
    if (sortedArr[i] + 1 !== sortedArr[i + 1]) {
      missedNum = sortedArr[i] + 1;
    }
  }
  arr.forEach(el =&gt; {
    if (arr.indexOf(el) != arr.lastIndexOf(el)) {
      duplicates.push(el);
    }
  });
  duplicates.forEach(el =&gt; {
    if (sortedDuplicates.includes(el) == false) {
      sortedDuplicates.push(el);
    }
  });

  var lastdup = sortedDuplicates.sort((a, b) =&gt; a - b);

  return [missedNum, lastdup];
}

function findDupsMiss2(arr) {
  const processedNumbers = {};
  const duplicates = {};
  const noDuplicates = {};

  const checkDupOrNot = (el, i) =&gt; {
    if (processedNumbers[el]) {
      duplicates[el] = el;
      delete noDuplicates[el];
    } else {
      noDuplicates[el] = el;
    }
    processedNumbers[el] = el;
  };

  arr.forEach(checkDupOrNot);

  const missedReduceFn = (missed, el, i, arr) =&gt;
    el + 1 !== arr[i + 1] ? el : missed;
  const missed = [
    ...Array(
      processedNumbers[Object.values(processedNumbers).length - 1]
    ).keys()
  ].reduce(missedReduceFn, null);

  return [missed, Object.values(duplicates)];
}

const data = [10, 9, 8, 9, 6, 1, 2, 4, 3, 2, 5, 5, 3];

const perf1 = measurePerf(findDupsMiss1, data);
console.log(findDupsMiss1(data), perf1);

const perf2 = measurePerf(findDupsMiss2, data);
console.log(findDupsMiss2(data), perf2);

const processIterations = async () =&gt; {
  const results = [];

  // # elements 1, 2, 4, 8, 16, 32, 64, ..., 262144, 524288
  for (let i = 0; i &lt; 20; i++) {
    const dataLength = 1 &lt;&lt; i;
    const randData = [...Array(dataLength).keys()].map(() =&gt;
      Math.floor(Math.random)
    );

    const [t1, t2] = await Promise.all([
      // For your sanity, start skipping findDupsMiss1 here at 11.
      // Maybe don't go more than 15 unless you like creating space heaters.
      i &lt; 11 ? measurePerf(findDupsMiss1, randData, 100) : "skipped",
      measurePerf(findDupsMiss2, randData, 100)
    ]);

    results.push({
      iteration: i,
      dataLength,
      t1: Number.isFinite(t1) ? Number(t1).toFixed(3) : t1,
      t2: Number.isFinite(t2) ? Number(t2).toFixed(3) : t2
    });
  }

  return results;
};

processIterations().then(results =&gt; {
  console.log(`\t# Elements\tt1\tt2\tt2:t1 ratio`);
  results.forEach(({ iteration, dataLength, t1, t2 }, i, arr) =&gt; {
    const prev = arr[i - 1] || {};
    const t2t1Ratio = Number(t2 / t1).toFixed(2);
    const t1Ratio = Number(t1 / prev.t1).toFixed(1);
    const t2Ratio = Number(t2 / prev.t2).toFixed(1);

    console.log(
      `${iteration}\t${dataLength}\t${t1}(${t1Ratio})\t${t2}(${t2Ratio})\t${t2t1Ratio}`
    );
  });
});




    # Elements  t1 avg          t2 avg          t2:t1 ratio 
0   1           0.002(NaN)      0.003(NaN)      1.50 
1   2           0.002(1.0)      0.004(1.3)      2.00 
2   4           0.003(1.5)      0.005(1.3)      1.67 
3   8           0.006(2.0)      0.006(1.2)      1.00 
4   16          0.005(0.8)      0.012(2.0)      2.40 
5   32          0.011(2.2)      0.016(1.3)      1.45 
6   64          0.031(2.8)      0.029(1.8)      0.94 
7   128         0.084(2.7)      0.048(1.7)      0.57 
8   256         0.270(3.2)      0.094(2.0)      0.35 
9   512         1.032(3.8)      0.186(2.0)      0.18 
10  1024        4.696(4.6)      0.372(2.0)      0.08 
11  2048        16.303(3.5)     0.749(2.0)      0.05 
12  4096        67.092(4.1)     1.492(2.0)      0.02 
13  8192        266.986(4.0)    3.018(2.0)      0.01 
14  16384       1081.774(4.1)   6.785(2.2)      0.01 
15  32768       skipped(NaN)    12.298(1.8)     NaN 
16  65536       skipped(NaN)    25.941(2.1)     NaN 
17  131072      skipped(NaN)    49.775(1.9)     NaN 
18  262144      skipped(NaN)    99.556(2.0)     NaN 
19  524288      skipped(NaN)    195.841(2.0)    NaN 


Notes:


Average time is in milliseconds
Item in () is the ratio to the previous time (i.e. line above)
Each iteration 100 runs for performance measuring
Stopped measuring algorithm 1 after 15 iterations, it's just too slow


Conclusion

As can be seen, the table confirms your algorithm, after a certain point, appears to settle into roughly a 4x output size based upon 2x input, where the other algorithm appears to settle around 2x, as expected. Also, a tipping point appears to consistently be around iteration #6 / 64 elements when algorithm #2 overtakes algorithm #1 and is more performant.