调用函数和创建函数实例之间的Javascript差异

Javascript difference between calling a function and creating an instance of a function

本文关键字:函数 Javascript 差异 之间 实例 创建 调用      更新时间:2023-09-26

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

示例:

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

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

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

当您调用new outer(1, 2)时,您已经使this(在"outer"中)成为对新对象的引用。当"inner"在"outer"内部调用时,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中观察到的怪异)

在Javascript中有4种方法可以使用函数每一个都改变了this的内容:

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

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

基本上就是我在这里写的