1

What advantages does ES6 has over ES5, regarding block scope functions? I mean the block looks quite similar in both the cases so what difference it makes, performance wise which approach is better to use?

ES6 Block

{
    function foo() {
        return 1;
    }

    foo() === 1;
    {
        function foo() {
            return 2;
        }

        foo() === 2;
    }
    foo() === 1;
}

ES5 Block

(function () {
    var foo = function () {
        return 1;
    }
    foo() === 1;
    (function () {
        var foo = function () {
            return 2;
        }
        foo() === 2;
    })();
    foo() === 1;
})();
Andy
  • 521
  • 3
  • 6
  • 22
  • 1
    I’d guess that the ES6 one is faster because there’s no function that needs to be created, called, and return a value. – Jed Fox Dec 07 '16 at 11:23
  • Thanks Jed, but will ES6 block get Hoisted? – Andy Dec 07 '16 at 11:34
  • I'm really interested to see how anyone plans to deduce what is better for performance, seeing there's quite a few JS engine implementations and they don't even operate the same way. Also this appears to be such a miniature scale "optimization", why would anyone even do it? It looks like more time is wasted asking this question than all the performance you'll ever get. What happened with right tool for the job? – Mjh Dec 07 '16 at 12:24
  • Why did you change `function foo` to `var foo = function`? – Bergi Dec 07 '16 at 15:41
  • That's not a block, that's an IIFE. – Bergi Dec 07 '16 at 15:42
  • You'll want to read [What are the precise semantics of block-level functions in ES6?](http://stackoverflow.com/q/31419897/1048572) – Bergi Dec 07 '16 at 15:43

1 Answers1

1

Here is a test to show which is fastest:

document.getElementById('btn').addEventListener('click', ({ target }) => {
  target.disabled = true;
  target.innerHTML = "Running…";
  const suite = new Benchmark.Suite();
  document.getElementById('ES6').style.fontWeight = '';
  document.getElementById('ES5').style.fontWeight = '';
  suite.add('ES6', () => {
    {
        function foo() {
            return 1;
        }
        foo() === 1;
        {
            function foo() {
                return 2;
            }
            foo() === 2;
        }
        foo() === 1;
    }
  }).add('ES5', () => {
    (function () {
        var foo = function () {
            return 1;
        }
        foo() === 1;
        (function () {
            var foo = function () {
                return 2;
            }
            foo() === 2;
        })();
        foo() === 1;
    })();
  })
  .on('cycle', ({target: bench}) => document.getElementById(bench.name).textContent = `${bench.name}: ~${Benchmark.formatNumber(bench.hz|0)} ops/sec (~${Benchmark.formatNumber(Math.round(1e9/bench.hz))} ns/op)`)
  .on('complete', function() {
    const el = document.getElementById(this.filter('fastest').map('name')[0]),
          hz = this.filter('fastest').map('hz')[0],
          others = this.filter('slowest').map('hz'),
          avg = others.reduce((a, b) => a + b, 0) / others.length;
    el.style.fontWeight = 'bold';
    el.textContent += ` \u{1f451} ${Math.round((1 - avg / hz) * 100, 2)}% faster`;
    target.disabled = false;
    target.innerHTML = "Run";
  })
  .run({ 'async': true });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.2/benchmark.min.js"></script>
<ul>
  <li id="ES6"></li>
  <li id="ES5"></li>
</ul>
<button id="btn">Run</button>

Results on my computer:

  • ES6: ~3,896,305 ops/sec (~257 ns/op) 40% faster
  • ES5: ~2,425,847 ops/sec (~412 ns/op)
Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
Jed Fox
  • 2,979
  • 5
  • 28
  • 38