JavaScript

JavaScriptで内部関数(名前空間に公開したくない関数)を用いる方法(とっても大事なクイズだよ!)

以下のコードを実行すると test2 関数の方が速いんですけど、みなさんこの理由わかりますか?
両方とも、add、sub という外部に公開したくない内部関数を定義する方法です。

31
31
test1: 6.410ms
test2: 3.527ms
const COUNT = 1000000

function test1(x, y) {
    function add(a, b) {
        return a + b
    }
    function sub(a, b) {
        return a - b
    }
    return add(x, 11) + sub(y, 22)
}

var test2 = (function () {
    function add(a, b) {
        return a + b
    }
    function sub(a, b) {
        return a - b
    }
    return function(x, y) {
        return add(x, 11) + sub(y, 22)
    }
}());

console.log(test1(10, 32))
console.log(test2(10, 32))

console.time('test1')
for (let i=0; i<COUNT; i++ ) test1(10, 32)
console.timeEnd('test1')
console.time('test2')
for (let i=0; i<COUNT; i++ ) test2(10, 32)
console.timeEnd('test2')

上記はブラウザで動作させるプログラムを作る場合の名前空間汚染を避ける手順ですが、Node.js の場合は

test3.js
function add(a, b) {
    return a + b
}
function sub(a, b) {
    return a - b
}
module.exports = function(x, y) {
    return add(x, 11) + sub(y, 22)
}

としておいて

main.js
const COUNT = 1000000
var test3 = require('./test3')
console.log(test3(10, 32))
console.time('test3')
for (let i=0; i<COUNT; i++ ) test3(10, 32)
console.timeEnd('test3')
//console.log(add(111,222)) // ← エラーになります。

でOKなので楽なんですね。