当前位置: 首页 > 知识库问答 >
问题:

嵌套函数中的函数上下文(“this”)

锺离飞鸣
2023-03-14

在Javascript中调用顶级函数时,函数中的this关键字引用默认对象(如果在浏览器中,则为窗口)。我的理解是,这是作为方法调用函数的一种特殊情况,因为默认情况下,它是在窗口上调用的(如John Resig的书《JavaScript忍者的秘密》第49页所述)。实际上,下面代码中的两个调用是相同的。

function func() {
  return this;
}

// invoke as a top-level function
console.log(func() === window); // true

// invoke as a method of window
console.log(window.func() === window); // true

到目前为止还不错...这是我不明白的部分:

当一个函数嵌套在另一个函数中并在未指定要调用的对象的情况下调用时,函数中的this关键字也会引用窗口。但无法在窗口上调用内部函数(请参见下面的代码)。

function outerFunc() {
  function innerFunc() {
    return this;
  }

  // invoke without window.* - OK
  console.log(innerFunc() === window); // true

  // invoke on window
  //window.innerFunc(); - error (window has no such method)
  console.log(window.innerFunc) // undefined
}

outerFunc();

嵌套函数在窗口上不可用是完全合理的,因为它毕竟是嵌套的...但是后来我不明白为什么这个关键字指的是窗口,好像这个函数是在窗口上调用的。我错过了什么?

编辑

下面是对以下重要答案的总结,以及我的一些后续研究。

>

函数上下文(this关键字的值)不取决于函数定义的位置/方式,而是取决于调用函数的方式。

假设代码没有在严格模式下运行,调用函数“正常”将使函数上下文设置为窗口(在浏览器中运行时,或在其他环境中运行相应的全局对象时)。

上述规则的一个例外是使用bind创建函数。在这种情况下,即使函数被“正常”调用,它也可能有窗口以外的上下文。也就是说,在这种情况下,上下文是由创建函数的方式决定的,而不是由调用函数的方式决定的。虽然严格来说这是不准确的,因为bind创建了一个新函数,该函数在内部使用应用调用给定的函数。该新函数的上下文仍将由其调用方式决定,但它通过使用应用来屏蔽其内部调用的函数的上下文。

通过调用“正常”,我指的是以下简单的调用方式:

myFunction()

为了完成这幅图,这里简要介绍了其他调用方式和相应的上下文:

>

  • 作为对象(方法)的属性,上下文就是对象

    使用apply或call-显式指定上下文

    使用新操作符(作为构造函数)-上下文是一个新创建的对象

    如有必要,请随时更新上述内容,以方便有类似问题的人。谢谢


  • 共有3个答案

    齐凯康
    2023-03-14
    匿名用户

    当函数被调用时,一个函数是否嵌套在另一个函数中与this的值无关。唯一重要的是:

    >

  • 如果函数是通过遍历对象上的属性找到的,那么this的值将是对该对象的引用:

    someObject.prop( whatever );
    

    函数是如何声明的并不重要。

    如果使用call()apply()调用函数,则this的值从第一个参数取到您使用的那些函数中的任何一个。

    如果您使用bind()为函数创建了绑定包装,则调用bind()时,this的值将与请求的值相同。

    如果您使用new作为构造函数调用函数,那么this将引用新创建的对象实例。

    否则,this要么是对全局上下文的引用,要么是未定义的(在严格模式或符合ES5的运行时)。

    当然,定义函数的代码中的“位置”很重要,因为范围包括它包含的任何符号,并且这些符号对函数都可用,而不管如何获得对它的引用。

  • 龙昊焱
    2023-03-14

    在JavaScript中,当在没有显式上下文的情况下调用函数时,上下文就是全局对象。对于web浏览器,全局对象是window

    此外,JavaScript具有函数作用域,因此函数中的任何变量或函数都不能在该函数之外的作用域中访问。这就是您无法访问窗口的原因。innerFunc

    寇丰
    2023-03-14

    您可以调用范围内的任何函数FunctionName()。因为您还没有在对象上调用它,所以它将在默认对象(窗口)的上下文中调用。(IIRC,如果您处于严格模式,它将在未定义的上下文中被调用)。

    上下文的默认对象与定义函数的位置或函数出现在哪个范围无关。它只是默认对象。

    如果函数是对象的属性,则可以将其称为reference。到对象函数(),它将在对象的上下文中调用,而不是在默认对象中调用。

    更改上下文的其他内容包括new关键字和applycallbind方法。

     类似资料:
    • 问题内容: Java编程语言是否有任何扩展使创建嵌套函数成为可能?在很多情况下,我需要创建在另一个方法或for循环的上下文中仅使用一次的方法。到目前为止,尽管用Javascript可以很容易地完成,但我迄今仍无法完成。 例如,这无法在标准Java中完成: 问题答案: Java 8引入了lambda。 该语法可在定义了一种方法的任何接口上使用。因此,您可以将其与一起使用,但不能与一起使用。 是jav

    • 问题内容: 我试图理解reactjs中的一些概念,但是我无法理解函数的嵌套。我创建了以下示例来调查我的担忧。 在下面的示例中,我呈现了一些内容,这些内容的价值来自一系列嵌套函数。但是,出现错误“未捕获的TypeError:无法读取未定义的属性’renderInnerContent’”。您能帮我了解发生了什么以及如何解决此问题吗?我的主要动机是了解如何将事物抽象为不同的功能。 问题答案: 未在该函数

    • 问题内容: 我得到了一段我不明白的javascript代码: 如何在另一个函数中定义一个函数?我们可以从my()函数外部调用pad2()吗? 请给它一些照明。谢谢 问题答案: 函数是JavaScript中变量的另一种类型(当然有些细微差别)。在另一个函数中创建一个函数会更改该函数的作用域,就像改变变量的作用域一样。这对于与闭包一起使用以减少总体全局名称空间污染尤其重要。 除非已将另一个函数中定义的

    • Scala 函数 我们可以在 Scala 函数内定义函数,定义在函数内的函数称之为局部函数。 以下实例我们实现阶乘运算,并使用内嵌函数: object Test { def main(args: Array[String]) { println( factorial(0) ) println( factorial(1) ) println( factor

    • 嗨,我是ReactJS平台的学生开发者。我以前在render方法中使用过类组件,但现在我学习了钩子和函数组件对它的重要性,就像每个Reactjs开发人员所知道的那样。我在使用嵌套组件时遇到问题,我面临如下错误: index.js:1警告:函数作为React子函数无效。如果返回组件而不是从渲染返回组件,可能会发生这种情况。或者你想调用这个函数而不是返回它 你能帮我解决这个问题吗?如何在返回部分有效地