2012-04-15 49 views
9

完整故事,請my other questionV8的內部 - 匿名的處理函數

基本上,我問,如果它是更有效地使用插座處理器命名功能如下代碼:

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足夠聰明地編譯一次匿名函數,並在匿名函數通常導致幾個函數實例被創建的情況下在不同的範圍內重用它們?例如,上面我所期望的action1action2的處理程序要創建一次connection事件,但處理程序,並disconnect爲每個連接創建。在另一個問題中,這是用命名函數解決的,但如果在V8中這是必要的,或者它會做一些優化,我更感興趣。

+0

注意,這無關與功能是有名或無名;它與您是否在每個連接上創建新功能有關。 (有關更多信息,請參閱我的答案。) – 2012-04-15 07:47:27

回答

6

是的。我在V8郵件列表中創建了asked a very similar question(在我的案例中涉及從構造函數中創建函數)。我得到的回答是,函數的代碼是「......一般重複使用......」,即使有一個單獨的函數對象每個(所要求的規範)的時間。


但請注意,您的問題與函數是命名還是匿名無關。在您的例子中,函數可以有一個名字:

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,你不必擔心。)