V8内部 - 匿名函数的处理

时间:2012-04-15 07:24:57

标签: javascript v8

有关完整报道,请查看my other question

基本上,我曾问过在以下代码中使用套接字处理程序中的命名函数是否更有效:

var app = require('express').createServer()
var io = require('socket.io').listen(app);

app.listen(8080);

// Some unrelated stuff

io.sockets.on('connection', function (socket) {
    socket.on('action1', function (data) {
        // logic for action1
    });

    socket.on('action2', function (data) {
        // logic for action2
    });

    socket.on('disconnect', function(){
        // logic for disconnect
    });
});

总体答案是肯定的(有关详情,请参阅上述链接),但ThiefMaster发布了以下评论:

  

我不熟悉V8的内部结构,但它可能足够聪明,只需编译一次该函数并重复使用它,只需添加不同的范围即可。

所以现在这是我的问题。在匿名函数通常导致创建多个函数实例的情况下,V8是否足够智能来编译匿名函数并在不同范围内重用它们?例如,上面我希望connection事件的处理程序可以创建一次,但是为每个连接创建action1action2disconnect的处理程序。在另一个问题中,这是通过命名函数解决的,但我更感兴趣的是,如果在V8中这是必要的,或者它会做一些优化。

1 个答案:

答案 0 :(得分:7)

是。我在V8邮件列表上asked a very similar question(在我的例子中与在构造函数中创建函数有关)。我得到的答复是函数的代码是“......通常重用...”,即使每次都有一个单独的函数 object (根据规范的要求)


但请注意,您的问题与函数是命名还是匿名无关。示例中的函数可以有一个名称:

io.sockets.on('connection', function handleConnection(socket) {
    socket.on('action1', function (data) {
        // logic for action1
    });

    socket.on('action2', function (data) {
        // logic for action2
    });

    socket.on('disconnect', function(){
        // logic for disconnect
    });
});

使用命名函数表达式,它完全有效并由V8正确处理。 (可悲的是,它是not handled correctly by IE8 and earlier,它在完全不同的时间创建了两个完全不同的功能。但是当你使用V8时,你不必担心它。)