回调内部变量的范围

时间:2016-03-09 12:51:06

标签: javascript node.js scope

var net = require('net');
net.createServer(function(socket){
    console.log('CONNECTED: ' + socket.remoteAddress +':'+ socket.remotePort);
    var id = '123';
    socket.on('data',function(data){
        console.log(id);
        setTimeout(function(){
            console.log(id);
        },5000);
    });
}).listen(10000,'');

在这段代码中它应该打印123和undefined对吗?但它打印123和123.根据我的理解,setTimeout在某个时间后执行,在那个时间点它无法访问id变量。我真的很困惑。为什么会发生这种情况,哪里出错了。

3 个答案:

答案 0 :(得分:2)

socket.on和setTimeout的回调都在定义id var的范围内。由于回调函数都没有定义自己的本地id,因此它们都会打印123。

答案 1 :(得分:0)

  

在这段代码中它应该打印123和undefined对吗?但它打印出来   123和123。

这是因为setTimeout函数没有本地id变量。

以下将打印您要查找的输出

 setTimeout(function(){  
        var id;
        console.log(id);
    },5000);

这是因为即使setTimeout函数也有自己的作用域,如果未在内部函数中定义变量,它将使用外部函数的作用域。

答案 2 :(得分:0)

注意:此polyfill仅运行浏览器。如果您在nodejs中使用此代码,则可以在某处更改..

/*  setTimeout argument supports    */
if (document.all && !window.setTimeout.isPolyfill) {
    var __nativeST__ = window.setTimeout;
    window.setTimeout = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
        var aArgs = Array.prototype.slice.call(arguments, 2);
        return __nativeST__(vCallback instanceof Function ? function () {
            vCallback.apply(null, aArgs);
        } : vCallback, nDelay);
    };
    window.setTimeout.isPolyfill = true;
}

if (document.all && !window.setInterval.isPolyfill) {
    var __nativeSI__ = window.setInterval;
    window.setInterval = function (vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */) {
        var aArgs = Array.prototype.slice.call(arguments, 2);
        return __nativeSI__(vCallback instanceof Function ? function () {
            vCallback.apply(null, aArgs);
        } : vCallback, nDelay);
    };
    window.setInterval.isPolyfill = true;
}

示例:

setTimeout(function(id){
            console.log(id);
        },5000,"hello");

// 5秒然后//你好;

详细信息this

更改代码:

var net = require('net');
net.createServer(function(socket){
    console.log('CONNECTED: ' + socket.remoteAddress +':'+ socket.remotePort);
    var id = '123';
    socket.on('data',function(data){
        console.log(id);
        setTimeout(function(id){
            console.log(id);
        },5000, id);
    });
}).listen(10000,'');