## Naming

`a`, `b`, `what` are not meaningful, descriptive and searchable names. `arr1`, `arr2` and `needle` are descriptive names.

## Code Duplication

There are two `for` loops in `countInArray` and both are same. A function can be created which will take array and _needle_ as arguments and return the count.

## Implicit globals

In below code, `x` is global. Since, `var` is not used to declare the variable, it is added to global scope. To make it _local_ to function use `var`, `let` or `const`. See [Why are global variables considered bad practice?][1]

      for (x = 0; x < b.length; x++) {
          if (!a.includes(b[x]) && !arr.includes(b[x]))
              arr.push(b[x])
      }


## Missing Semi-Colons

Although a minor thing, but this could lead to unexpected results in some cases. I recommend to add semi-colons explicitly and not rely on automatic semicolon insertion. See [What are the rules for JavaScript's automatic semicolon insertion (ASI)?][2]

## Taking advantage of ES2015

`include` is used in code which means that your environment supports ES2015. However, you're not taking advantage of ES2015 features.


----------

With the last point above, I'll suggest you to use below equivalent code

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

    function customMergeArrays(arr1, arr2) {
        'use strict';

        let elementCount = (haystack, needle) => haystack.filter(el => el === needle).length;
        let uniqueElements = [...new Set(arr1.concat(arr2))];

        let result = [];
        uniqueElements.forEach(function(el) {
            let aIncludes = arr1.includes(el);
            let bIncludes = arr2.includes(el);

            if ((aIncludes && bIncludes === false) || (aIncludes === false && bIncludes)) {
                result.push(el);
            } else if (aIncludes && bIncludes && elementCount(arr1, el) === elementCount(arr2, el)) {
                result.push(el);
            }
        });
        return result.sort((a, b) => a - b);
    }

    let firstArr = [1, 3, 40, 40, 50, 60, 60, 60];
    let secondArr = [2, 40, 40, 50, 50, 65];
    let mergedArray = customMergeArrays(firstArr, secondArr);
    console.log(mergedArray);

<!-- end snippet -->

**Explanation:**

[Strict mode][3]

`elementCount` is the function that uses new [Arrow function][4] and returns the count of the element occurred in the array. This method accepts array and element to search.

`[...new Set(arr1.concat(arr2))]` first concats two arrays and pass it to [`Set`][5] and using [spread syntax][6] array of unique elements is created from set.

Then, iterating over this array of unique elements and push them into results array by checking the conditions.

To compare the performance, I've created [JSPerf][7] test.

Here's screenshot for reference.

[![JSPerf Comparison][8]][8]


  [1]: http://stackoverflow.com/q/10525582/2025923
  [2]: http://stackoverflow.com/q/2846283/2025923
  [3]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode
  [4]: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions
  [5]: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Set
  [6]: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Spread_operator
  [7]: https://jsperf.com/merge-with-case/1
  [8]: https://i.sstatic.net/UuoLX.png