📜  javascript 在回调中访问 this - Javascript (1)

📅  最后修改于: 2023-12-03 15:31:41.791000             🧑  作者: Mango

在回调中访问this

在JavaScript中,回调函数是一种非常常见的函数类型,它们通常用于异步操作,例如Ajax请求或事件监听器。然而,访问回调函数内部的的this值可能比较困难,因为它不能像在函数中一样被简单地引用。本文将向您解释如何在回调函数中访问this值,并提供实用的代码示例。

识别this的问题

在JavaScript中,关键字this是一个非常有用的序列。它通常用于访问当前执行上下文中的属性和方法。由于它非常地灵活和上下文相关,因此尤其对于回调函数,它的使用必须经过仔细地考虑。

例如,在下面的代码中,我们可以声明一个对象,然后给它添加一个方法:

var obj = {
  name: 'John',
  greet: function() {
    console.log('Hello, ' + this.name);
  }
};

在这个示例中,我们定义了一个对象obj,它包含一个名为“John”的属性和一个名为greet的方法。该方法通过访问当前对象中的名称属性来向控制台输出一个问候消息。因此,当我们调用obj.greet()时,将打印“Hello,John”到控制台。

迁移this

然而,当我们将回调函数放入上下文中时,情况会变得略微复杂。考虑以下带有回调函数的代码:

var obj = {
  name: 'John',
  greet: function() {
    setTimeout(function() {
      console.log('Hello, ' + this.name);
    }, 1000);
  }
};

obj.greet();

在这个示例中,我们已经更新了greet方法,以在内部使用setTimeout函数,该函数将在1秒后运行。但是,如果我们这样去运行,我们将在控制台上看到一个错误:

Hello, undefined

为什么会发生这样的事情?原因是在setTimeout函数中的this值将不再是obj对象,而是指该函数自身的上下文。更确切地说,在此情况下,this将指向全局上下文,而非我们所希望的对象。

为了解决此问题,我们可以简单地将当前对象的引用存储在单独的变量中,并在setTimeout函数中使用该变量。例如,我们可以将以下代码替换到greet函数:

var obj = {
  name: 'John',
  greet: function() {
    var self = this;

    setTimeout(function() {
      console.log('Hello, ' + self.name);
    }, 1000);
  }
};

obj.greet();

在这个新的示例中,我们已经包装setTimeout函数的this值在局部变量self中,并在其中存储一个对当前obj实例的引用。然后,在setTimeout回调函数中,我们使用该self变量访问当前上下文中的名称属性。

这种技巧基本上是JavaScript开发人员的必备技能,因为它为您提供了在回调函数中访问很多不同值的灵活性。您甚至可以使用简单的结构将多个对象的引用存储在同一个变量中。例如,在下面的示例中,我们将obj和另一个名称为person的对象引用存储在同一个变量中,并在回调中使用它们:

var obj = {
  name: 'John',
  greet: function() {
    var that = {
      obj: this,
      person: { name: 'Jane' }
    };

    setTimeout(function() {
      console.log('Hello, ' + that.obj.name);
      console.log('Hello, ' + that.person.name);
    }, 1000);
  }
};

obj.greet();

在这个示例中,我们已经定义了一个叫做that的新对象,它包含了一个obj属性和一个person属性。其中,obj属性的值是调用greet方法的对象(即obj本身),而person属性包含一个新的对象,其中包含一个名为Jane的名称属性。

在setTimeout回调中,我们可以使用that.obj和that.person来访问这些对象中的属性。

总结

回调函数是JavaScript编程中强大的思想,因为它们增强了异步编程的能力。

本文提供了一些示例,说明了如何在回调函数内部访问当前对象的名称属性。我们希望这篇文章能够帮助您更好地管理回调函数和上下文,并在编写JavaScript代码时更加自信。