HOWTO · JavaScript

使用 JavaScript 将此关键字传递给函数

本文将帮助你了解 this 关键字对给定 JavaScript 函数的设置。

本页内容

this 关键字是 JavaScript 中的一个关键概念。在 JavaScript 中,this 是对象的句柄。

与此相关的对象可以根据它是公共的、实体上的还是构造函数中的而直观地改变。它也可以根据函数概念过程 bind、call 和 apply 的数量明显变化。

在本教程中,你将发现 this 关键字与依赖上下文直观相关的内容,你将发现如何使用 bind、call 和 apply 方法来识别 this 的值直接地。

在 JavaScript 中使用 call() 和 apply() 方法

call() 和 apply() 都做同样的事情:它们调用一个给定上下文和可选参数的函数。这两种方法的唯一区别是 call() 接受一个接一个的参数,而 apply() 接受一个参数数组。

在这个例子中,我们将创建一个对象和一个引用它但没有任何 this 上下文的函数。

例子:

const fruit = {
  name: 'Apple',
  location: 'Nepal',
} function summ() {
  console.log(`${this.name} is found in ${this.location}.`)
} summ()

输出:

"result is found in https://fiddle.jshell.net/_display/?editor_console=true."

因为 summ 和 fruit 是不相关的,所以当全局对象搜索这些属性时,单独执行 summ 将是未定义的。但是,你可以使用 call 和 apply 在方法上调用 this 水果上下文。

const fruit =
    {
      name: 'Apple',
      location: 'Nepal',
    }

    function summ() {
      console.log(`${this.name} is found in ${this.location}.`)
    }

    summ.call(fruit)

运行代码

const fruit =
    {
      name: 'Apple',
      location: 'Nepal',
    }

    function summ() {
      console.log(`${this.name} is found in ${this.location}.`)
    }

    summ.apply(fruit)

运行代码

输出:

"Apple is found in Nepal."

现在,当使用这些策略时,fruit 和 summ 之间存在联系。让我们确保我们在同一个页面上并且知道 this 是什么。

function printhis() {
  console.log(this)
}
printhis.call(fruit)

运行代码

function printhis() {
  console.log(this)
}
printhis.apply(fruit)

运行代码

输出:

{
  location: "Nepal",
  name: "Apple"
}

this 是在这种情况下作为参数提供的对象。call() 和 apply() 在这方面是相似的,但有一个细微的区别。

除了 this 上下文之外,你还可以选择传递额外的参数作为第一个参数。使用 call() 方法,你要传递的每个附加值都作为单独的参数提交。

const fruit =
    {
      name: 'Apple',
      location: 'Nepal',
    }

    function longerSumm(family, year) {
      console.log(`${this.name} is found in ${this.location}. It is from ${
          family} family found in ${year}.`)
    }

    longerSumm.call(fruit, 'malius', 1900)

运行代码

输出:

"Apple is found in Nepal. It is from malius family found in 1900."

如果你使用 apply() 发送相同的参数,则会发生这种情况。

const fruit =
    {
      name: 'Apple',
      location: 'Nepal',
    }

    function longerSumm(family, year) {
      console.log(`${this.name} is found in ${this.location}. It is from ${
          family} family found in ${year}.`)
    }

    longerSumm.apply(fruit, 'malius', 1932)

运行代码

输出:

Uncaught TypeError: CreateListFromArrayLike called on non-object

相反,你必须将数组中的所有参数传递给 apply()。

const fruit =
    {
      name: 'Apple',
      location: 'Nepal',
    }

    function longerSumm(family, year) {
      console.log(`${this.name} is found in ${this.location}. It is from ${
          family} family found in ${year}.`)
    }

    longerSumm.apply(fruit, ['malius', 1900])

输出:

"Apple is found in Nepal. It is from malius family found in 1900."

运行代码

单独传递参数和在数组中传递参数之间的差异很小。使用 apply() 可能更容易,因为如果任何参数细节发生变化,它不需要修改函数调用。

在 JavaScript 中使用 bind() 方法

你可能需要重复调​​用具有另一个对象的 this 上下文的方法,在这种情况下,你可以使用 bind() 方法来构造一个带有有意链接的 this 的新函数。

const fruit = {
  name: 'Apple',
  location: 'Nepal',
} function summ() {
  console.log(`${this.name} is found in ${this.location}.`)
} const newSummary = summ.bind(fruit)
newSummary()

输出:

"Apple is found in Nepal."

运行代码

当你在本例中调用 newSummary 时,它将始终返回与其相关的原始值。如果你尝试将新的 this 上下文绑定到它,它将失败。

因此,你始终可以依靠链接函数来提供你期望的 this 值。

const fruit = {
  name: 'Apple',
  location: 'Nepal',
} function summ() {
  console.log(`${this.name} is found in ${this.location}.`)
} const newSummary = summ.bind(fruit)
newSummary()

const fruit2 = {
  name: 'Mango',
  location: 'Terai',
}
newSummary.bind(fruit2)
newSummary()

输出:

"Apple is found in Nepal."

运行代码

即使此示例尝试第二次绑定 newSummary,它仍保留第一次绑定时的原始上下文。