首页 文章

关闭误解

提问于
浏览
1

我以为我理解闭包但我猜不是 . 这是一个代码示例,显示了我遇到的问题 . 我希望代码能够将'text'打印到控制台 .

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

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

我使用内部函数作为cb运行外部函数 . 在这种情况下,我得到的var文本是未定义的 . 我认为由于js闭包,内部函数仍然会引用text变量 .

//Run outer with a cb of inner.
outer(inner);

尝试使用匿名函数作为cb并给出相同的文本未定义错误 .

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

我在这里缺少什么想法?我在我的程序的其他方面使用闭包没有问题,但显然我不完全理解发生了什么 .

5 回答

  • 0

    这里的问题不是闭包的结果,因为它是范围...而且我更喜欢在父/子关系方面考虑JavaScript范围 .

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

    enter image description here

    上面的图片是Google图片中的通用和无耻窃取,但用于解释“A”是父作用域; “B”和“C”在父范围内定义 . “D”和“E”在“B”的范围内定义 - 因此“C”不能看到“D”或“E” .

    在您的示例中,"parent"范围是定义这两个函数的上下文(可能是 window ) . 其中一个"children"方法的范围(上下文)中的任何内容都可以在其上方的作用域(上下文)中看到 defined - 因此 outer() 中的代码知道 inner() 存在(两者都在父作用域中定义),但是两种功能都不能看到对方内部存在的东西 . (注意:父作用域(大概是 window )也看不到每个函数内部的定义;它只知道存在的函数 . )

    但由于可见性仅向上移动, inner() 内的范围不知道 text 因为它是在 outer() 内定义的 .

  • 2

    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!
    });
    
  • 1

    outer 内调用 cb 时没有(相关)闭包 .

    如果您在 outer 内创建了 inner ,那么您将关闭 text ,并且在调用 inner 时会看到它的值 - 但您不是 .

    text 里面 inner 是全球 text .

  • 0

    闭包允许函数访问定义它们的作用域中的变量,而不是它们被调用的作用域 .

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

    var text = 'some text';
    var inner = function() {
      console.log(text);
    };
    
    text = 'changed text'
    
    var outer = function(cb) {
      cb();
    };
    
    outer(inner);
    
  • 3

    您还应该学习术语Lexical Scoping以了解情况 . 变量/函数的范围由其在源代码中的位置定义 .

    在第二个/外部函数中声明函数然后从该函数返回(第二个/外部)时,将创建一个闭包 . 在您的情况下, inner 函数未在 outer 函数内声明 .

    您可以重新安排代码以形成一个闭包:

    function outer() {
        var text = 'text';
    
        function inner(){
            console.log(text);
        };
    
        return inner;
    }
    
    var foo = outer();
    
    foo();      // text
    

相关问题