【问题标题】:What is and how to determine the calling context of an invoked method or function within another function?什么是以及如何确定另一个函数中调用的方法或函数的调用上下文?
【发布时间】:2011-10-30 19:10:31
【问题描述】:

另一个函数中被调用的方法或函数的调用上下文是什么?

在浏览器中,默认调用上下文是window 对象。在各种情况下,我该如何避免这种情况?

如果一个函数在包含函数中被调用——例如,由theFunction();——,被调用函数的调用上下文是包含函数吗?

在这两个例子中

(function ()
{
    something.initialize();
}());

(function ()
{
    something.initialize.call(this);
}());

...,调用上下文是否相同?

【问题讨论】:

    标签: javascript function methods call


    【解决方案1】:

    它们不一样。 在下面我假设你在提到上下文时谈论的是this

    在第一个示例中,initialize 内部,this 将引用 something。在第二个中,它将引用全局对象,即浏览器中的window


    this 所指的内容取决于函数的调用方式。有五种情况:

    • func(),调用“独立”函数:this 指的是全局对象。

    • new func(),调用函数作为构造方法:this 将引用继承自 func.prototype 的空对象。

    • obj.func(),调用函数作为对象的属性:this 将引用对象obj

    • func.apply(foo)func.call(foo),使用applycall 调用函数:this 指的是作为第一个参数传递的对象。

    ECMAScript 5 还引入了.bind() [MDN],它使您能够将this 绑定到某个对象, 不会立即调用该函数。


    现在您明白为什么在第二个示例中,initializethis 将引用 window

    外部函数称为“独立”(第一种情况),因此其中的this 将引用window。接下来,您将this 传递给call,这会将this 内部的initialize 设置为window(第四种情况)。


    进一步阅读:

    • MDN - this,用一些例子解释了我上面写的所有内容。

    【讨论】:

      【解决方案2】:

      不,它们不一样。 call 方法的第一个参数设置该函数内this 的值;示例 1 的 this 理论上应该包含对 something 的引用;示例 2 的 this 对应于您的自执行函数的 this

      【讨论】:

        【解决方案3】:

        函数在被调用时可用的环境是基于几个方面的。

        1. this 绑定与示例中的初始化方法不同
        2. 不是的实际参数绑定以及特殊arguments 对象的绑定
        3. 函数名的绑定,如果有的话
        4. 创建函数时的环境链。这是术语“关闭”的“关闭”部分。当函数对象存在时,javascript 函数会“关闭”范围内的所有变量。

        在您的示例中,只有 1 受选择使用 call 的影响,其效果是将 this 而不是 something 作为方法主体中的 this 值传递。

        规范的相关部分从10.4.3部分开始

        当控制进入函数对象F中包含的函数代码的执行上下文时,执行以下步骤,调用者提供thisArg,调用者提供argumentsList:...

        【讨论】:

          【解决方案4】:

          函数不会创建上下文,除非它是构造函数(使用new 调用的函数)。

          在您的第二个示例中,上下文是undefined(它被转换为全局对象window)。在 ES5 严格模式下它不会被转换成任何东西。

          我推荐 John Resig 的 interactive JavaScript tutorial 关于上下文的主题。

          【讨论】:

            猜你喜欢
            • 2021-07-03
            • 2020-06-02
            • 2015-01-03
            • 1970-01-01
            • 1970-01-01
            • 2021-07-10
            • 1970-01-01
            • 2010-11-15
            • 2020-04-16
            相关资源
            最近更新 更多