Javascript 结束误解

Javascript 结束误解,javascript,closures,Javascript,Closures,我以为我懂闭包,但我想不懂。下面是一个代码示例,它显示了我遇到的问题。我希望代码将“文本”打印到控制台 var inner = function() { console.log(text); }; var outer = function(cb) { var text = 'text'; cb(); }; 我运行外部函数,内部函数作为cb。在这种情况下,我得到的var文本是未定义的。我认为由于js闭包,内部函数仍然会引用文本变量 //Run outer with a cb of

我以为我懂闭包,但我想不懂。下面是一个代码示例,它显示了我遇到的问题。我希望代码将“文本”打印到控制台

var inner = function() {
  console.log(text);
};

var outer = function(cb) {
  var text = 'text';
  cb();
};
我运行外部函数,内部函数作为cb。在这种情况下,我得到的var文本是未定义的。我认为由于js闭包,内部函数仍然会引用文本变量

//Run outer with a cb of inner.
outer(inner);
尝试使用匿名函数作为cb,并给出未定义文本的相同错误

//Anonymous
outer(function() {
  console.log(text);
});

你知道我遗漏了什么吗?我在程序的其他区域使用闭包没有问题,但显然我不完全理解发生了什么。

text
未定义-这不是闭包问题,而是不向回调传递参数的问题:

var outer = function(cb) {
    var text = 'text';
    cb(text); //note the parameter pass in here
};

outer(function(textParam) { //and now the callback passed in accepts a param
    console.log(textParam)  //name this param whatever you want!
});

text
未定义-这不是闭包问题,而是不向回调传递参数的问题:

var outer = function(cb) {
    var text = 'text';
    cb(text); //note the parameter pass in here
};

outer(function(textParam) { //and now the callback passed in accepts a param
    console.log(textParam)  //name this param whatever you want!
});
调用
cb
内部
外部
时没有(相关)闭包

如果您在
内部
外部
中创建了
内部
,您将关闭
文本
,并且在调用
内部
时您将看到它的值,但您没有

内部的
文本
是全局的
文本

在调用
cb
内部
外部
时,没有(相关的)闭包

如果您在
内部
外部
中创建了
内部
,您将关闭
文本
,并且在调用
内部
时您将看到它的值,但您没有


内部的
文本
是全局的
文本

这里的问题不是闭包的结果,而是范围。。。我更喜欢从父/子关系的角度来考虑JavaScript的作用域

任何作用域实体(如函数)都可以访问其继承的“父”作用域中定义的内容(可见性向上移动)——但“父”作用域看不到“子”作用域的内部,同一作用域的子作用域也看不到彼此的内部

上面的图片是通用的,无耻地从谷歌图片中盗取,但用来解释“A”是父范围;“B”和“C”是在父范围内定义的。“D”和“E”是在“B”的范围内定义的,因此“C”不能看到“D”或“E”

在您的示例中,“父”范围是定义这两个函数的上下文(可能是
window
)。在其中一个“子”方法的作用域(上下文)中定义的任何东西都可以看到它上面的作用域(上下文)中定义的东西,因此
outer()
中的代码知道
internal()
存在(两者都是在父作用域中定义的),但这两个函数都无法看到另一个函数中存在的内容。(注意:父作用域(可能是
窗口
)也看不到每个函数中定义的内容;它只知道函数存在。)


但是因为可见性只向上移动,所以
internal()
内的作用域不知道
文本
,因为它是在
outer()
内定义的,这里的问题不是闭包的结果,因为它是作用域。。。我更喜欢从父/子关系的角度来考虑JavaScript的作用域

任何作用域实体(如函数)都可以访问其继承的“父”作用域中定义的内容(可见性向上移动)——但“父”作用域看不到“子”作用域的内部,同一作用域的子作用域也看不到彼此的内部

上面的图片是通用的,无耻地从谷歌图片中盗取,但用来解释“A”是父范围;“B”和“C”是在父范围内定义的。“D”和“E”是在“B”的范围内定义的,因此“C”不能看到“D”或“E”

在您的示例中,“父”范围是定义这两个函数的上下文(可能是
window
)。在其中一个“子”方法的作用域(上下文)中定义的任何东西都可以看到它上面的作用域(上下文)中定义的东西,因此
outer()
中的代码知道
internal()
存在(两者都是在父作用域中定义的),但这两个函数都无法看到另一个函数中存在的内容。(注意:父作用域(可能是
窗口
)也看不到每个函数中定义的内容;它只知道函数存在。)


但是,由于可见性只向上移动,
internal()
内的作用域不知道
文本
,因为它是在
outer()
内定义的,闭包允许函数访问定义它们的作用域中的变量,而不是调用它们的作用域

修改您的示例,下面将打印“更改的文本”


闭包允许函数在定义变量的范围内访问变量,而不是在调用变量的范围内访问变量

修改您的示例,下面将打印“更改的文本”


你也应该学习这个术语来了解情况。变量/函数的范围由其在源代码中的位置定义

当在第二个/外部函数中声明函数,然后从该函数返回(第二个/外部)时,将创建闭包。在您的情况下,
内部
函数不是在
外部
函数中声明的

您可以重新安排代码以形成闭包,如下所示:

function outer() {
    var text = 'text';

    function inner(){
        console.log(text);
    };

    return inner;
}

var foo = outer();

foo();      // text

你也应该学习这个术语来了解情况。变量/函数的范围由其在源代码中的位置定义

当在第二个/外部函数中声明函数,然后从该函数返回(第二个/外部)时,将创建闭包。在您的情况下,
内部
函数不是在
外部
函数中声明的

您可以重新安排代码以形成闭包,如下所示:

function outer() {
    var text = 'text';

    function inner(){
        console.log(text);
    };

    return inner;
}

var foo = outer();

foo();      // text
感谢