Javascript 回调范围问题

标签 javascript function scope

我正在阅读 Douglas Crockford 的关于 Javascript 的书,并且对函数作用域部分有一些问题。我的印象是回调函数的 this 值绑定(bind)到调用回调的函数的 this 值(在本例中为 doSomethingAsync)。但是,当我运行此代码时,会打印 foo ,但就 doSomethingAsync 而言, foo 是未定义的。这难道不意味着回调也无权访问这个变量吗?

function doSomething() {
  var foo = "foo";
  doSomethingAsync(function callback() {
    console.log(foo); //prints foo
  });
}

最佳答案

this 和变量彼此非常不同。

this 主要由如何调用函数设置,而不是在定义位置设置,尽管绑定(bind)函数和 ES6 的箭头函数改变了这一点(更多内容见下文)。您的回调未绑定(bind),也不是箭头函数,因此您提供的 doSomethingAsync 回调中 this 的值将由 doSomethingAsync 的方式确定 调用该函数。如果它只是将其作为独立函数调用:

callback();

...那么this将是未定义(在严格模式下)或对全局对象的引用(在松散模式下)。

但是如果它调用它并指定 this 值:

// By making it an object property and using that to call it:
var obj = {callback: callback};
obj.callback(); // `this` will be `obj`

// By using Function#call or Function#apply
callback.call(foo); // `this` will be `foo`

...那么将会有所不同。

更多(在我的博客上):

不过,函数范围内的变量是由定义该函数的位置决定的。您的回调称为闭包,这意味着它对创建它的上下文(以及周围的上下文,等等,直到并包括全局上下文)有一个持久的引用,包括变量和该上下文中的其他一些东西。因此,当您的回调引用 foo 时,JavaScript 引擎首先在回调中查找,如果没有找到任何名为 foo 的内容,则会查看包含的上下文。在那里找到 foo ,它就会使用它。

但是,闭包所具有的上下文引用包含this(箭头函数除外),因为this更像是一个函数参数比变量(箭头函数除外)。

更多(在我的博客上):

<小时/>

“绑定(bind)”函数是从 Function#bind 获得的函数。它们的特点之一是它们的 this 值由您提供的 Function#bind 参数设置,忽略调用它们时提供的参数(如果有)。

ES6“箭头”函数do从创建它们的上下文继承它们的this,这使得它们与其他类型的函数非常不同。

关于Javascript 回调范围问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30531295/

相关文章:

javascript - 我无法让我的网站平滑滚动

python - Python简介,导致函数打印true

Kotlin 自定义作用域函数返回类型未按预期运行

javascript - 允许 JavaScript 闭包从父级作用域继承变量

python - 使用函数从指定索引开始对 Python 中不同长度的列表求和

scope - 符号表如何与静态链和作用域相关?

Javascript - 如何将 'br' 添加到段落中

javascript - 关于自己的 REST API 和使用 3rd 方 API 获取的问题

javascript - 打开多个模态 Materialise CSS

c++ - 为什么用作数组大小的函数的常量参数会出错?