简体   繁体   English

回调内部变量的范围

[英]Scope of variable inside callbacks

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,'');

In this code it should print 123 and undefined right? 在此代码中,它应该打印123并且未定义,对吗? but it prints 123 and 123. As per my understanding setTimeout executes after sometime, at that point of time it cannot access id variable. 但它显示123和123。根据我的理解,setTimeout在某个时间后执行,在那个时间点它无法访问id变量。 I am really confused. 我真的很困惑。 why is this happening and where am i wrong. 为什么会这样,我在哪里错了。

The callbacks for the socket.on and for the setTimeout are both inside the scope that defines the id var. socket.on和setTimeout的回调都在定义id var的范围内。 Since neither callback defines its own local id they both print 123. 由于两个回调均未定义其自己的本地id因此它们均会打印123。

In this code it should print 123 and undefined right? 在此代码中,它应该打印123并且未定义,对吗? but it prints 123 and 123. 但它会打印123和123。

That is because setTimeout function doesn't have local id variable. 那是因为setTimeout函数没有本地id变量。

Following will print the output you are looking for 以下将打印您要查找的输出

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

This is because even though setTimeout's function also has its own scope, it will use the scope of outer function if the variable is not defined in the inner function. 这是因为即使setTimeout的函数也具有自己的作用域,但如果未在内部函数中定义变量,它将使用外部函数的作用域。

Note: this polyfill only run browser. 注意:此polyfill仅运行浏览器。 If you use this code in nodejs, you change somewhere.. 如果在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;
}

Example: 例:

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

//5 second then //hello; // 5秒然后// hello;

Detail info this 详细信息

Changed Code: 更改的代码:

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,'');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM