17

我试图理解为什么在直接调用外部函数时内部函数可以访问外部函数的公共属性,但在将其分配给变量时不能访问?

例子:

function outer(x,y){

    this.x = x;
    this.y = y;

    function inner(){
        alert(this.x);       
    }

    inner();
}

outer(1,2); //As expected, alerts 1
var func = outer(1,2) //Also alert 1
var func2 = new outer(1,2); //Alerts undefined

我尝试的一件事是从中删除this关键字alert(this.x);,它确实适用于所有三种情况。但是,如果我确实删除了this关键字,我将访问传入的参数,而不是公共变量,这绝对不是所需的操作。有人可以解释这种行为吗?

4

2 回答 2

21

当您outer(1, 2)这样调用时,this是对 的引用window,因此“x”和“y”实际上是全局变量。这就是为什么inner()可以访问“x”。

当您调用时,new outer(1, 2)您已导致this(在“外部”中)成为对新对象的引用。当在“outer”内部调用“inner”时,this仍然会引用window,所以没有“x”。

的值this是针对每个函数调用确定的,并且该值仅取决于该调用的细节。因此,您通过调用“外部”的事实new对“内部”的内部调用没有影响——因为您只是将函数调用为inner();,该this函数内部的值将是对window(好吧,全局上下文,无论是)。

以下是this可以在调用函数时设置的方法:

  1. 如果函数是通过new操作符调用的,那么this将引用一个新创建的对象。
  2. 如果对函数的引用是通过对对象 ( foo.someFunction()) 的属性查找获得的,this则将是对该对象的引用。
  3. 如果函数是通过.call().apply()从函数原型调用的,那么this将引用使用这些函数中的任何一个的第一个参数,必要时强制为对象值。
  4. 如果函数是通过简单的“裸”引用调用的,那么this将引用全局上下文(window在浏览器中)。编辑— Šime Vidas 在上面的评论中指出,在严格模式下,这种情况会导致this存在null(这确实更有意义,并且可以避免在 OP 中观察到的怪异)。
于 2012-08-23T13:23:49.750 回答
8

有 4 种方法可以在 Javascript 中使用函数,每种方法的作用都是改变其内容this

  • 函数调用:this = 全局对象(浏览器中的窗口)
  • 方法调用:this = 调用它的对象。
  • 构造函数调用: this = 您正在创建的新对象。
  • 调用/应用调用:this = 您传递的对象。

在您的情况下this == window,当您直接调用函数(outer())但如果您使用 new(new outer())调用,那么它将是您正在创建的新对象。

基本上我在这里写的

于 2012-08-23T13:27:38.980 回答