因此,我在研究回调的概念,遇到了一种情况,我想确保我知道我以为发生了什么,实际上正在发生。

function greet(callback) { // 'greet' function takes a callback
  var greeting = "hi";     // 'greeting' variable is set in the scope
  callback()               // 'callback' function is invoked
}

greet(
function() {
  console.log(greeting)
});

//Console logs nothing


Sorta很奇怪,您希望callback()查找其下一个最接近的范围并找出问候是什么。但是,一旦我向全局执行上下文声明了greeting变量,问候语便会记录在控制台中。

var greeting = 'hi'        // 'greeting' variable is set in global context

function greet(callback) { // 'greet' function takes a callback
  callback()               // 'callback' function is invoked
}

greet(
function() {
  console.log(greeting)
});

//Console logs: 'hi'


这是因为从技术上来说,记录变量的callback()函数实际上是在全局上下文中定义的,并且只是在greet()内部调用?因此,它不会像普通的函数表达式那样首先在greet()内部查找,而是直接进入全局上下文,因为这是它的定义位置。

我只是想确保我了解这里发生的事情,而不是我没有意识到的一些奇怪的范围/块问题。

最佳答案

您是对的-该函数可以访问其定义的范围。

您的示例实际上是这样的(将回调函数移至其自己的函数):

var greeting = 'hi';

function greet(callback) {
    callback();
}

function logGreeting() {
    console.log(greeting);
}

greet(logGreeting);


如您所见,由于logGreeting是在相同(或更高)范围内定义的,因此此时可以访问greeting

但是,当我们将greeting移到greet函数中时:

function greet(callback) {
    var greeting = 'hi';
    callback();
}

function logGreeting() {
    console.log(greeting);
}

greet(logGreeting);


greeting不再与logGreeting在相同或更高的范围内,而是完全在不同的范围内,因此logGreeting不能向上看整个范围以查找greeting

logGreeting可以访问的范围是定义它的范围,而不是被调用的范围,因此,像您在问题中提到的那样,用callback()调用它时,它不会评估该范围。

10-07 17:28