调用函数和创建函数实例之间的Javascript区别

时间:2012-08-23 13:20:59

标签: javascript

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

示例:

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关键字,我将访问传入的参数,而不是公共变量,这绝对不是所需的操作。有人可以解释这种行为吗?

2 个答案:

答案 0 :(得分:17)

当你像outer(1, 2)那样召唤时,thiswindow的引用,所以“x”和“y”实际上是全局变量。这就是inner()可以访问“x”的原因。

当您致电new outer(1, 2)时,您已将this(在“外部”中)作为对新对象的引用。当在“外部”内部调用“内部”时,this仍将引用window,因此没有“x”。

每个函数调用都会确定this的值,该值仅取决于该调用的详细信息。因此,您通过new调用“外部”的事实对内部调用“内部”没有影响 - 因为您只需将函数称为inner();,其中this的值为函数将是window的引用(嗯,全局上下文,无论是什么)。

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

  1. 如果通过new运算符调用该函数,则this将引用新创建的对象。
  2. 如果通过对象(foo.someFunction())的属性查找获得对函数的引用,则this将是对该对象的引用。
  3. 如果函数是通过函数原型中的.call().apply()调用的,那么this将引用第一个参数,使用这些函数中的任何一个,强制转换为对象值如果有必要的话。
  4. 如果通过简单的“裸”引用调用该函数,则this将引用全局上下文(浏览器中的window)。 编辑 - ŠimeVidas在上面的评论中指出,在严格模式下,这种情况导致thisnull(这实际上更有意义,并且会避免OP中观察到的怪异。

答案 1 :(得分:6)

在Javascript中有4种方法可以使用函数 每个人所做的是改变this的内容:

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

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

基本上我写的是here