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

调用函数和创建函数实例之间的Javascript差异,javascript,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 =

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

例如:

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.x)中删除
this
关键字并且它对所有三种情况都有效。但是,如果我删除
this
关键字,我将访问传入的参数,而不是公共变量,这肯定不是所需的操作。有人能解释这种行为吗

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

当您调用
newouter(1,2)
时,您已使
(在“outer”中)成为对新对象的引用。当在“外部”内部调用“内部”时,
仍将引用
窗口
,因此没有“x”

的值是为每个函数调用确定的,该值仅取决于该调用的细节。因此,通过
new
调用“outer”对内部调用“inner”没有影响,因为您只需将函数调用为
inner()
,该函数中的
这个
的值将是对
窗口
的引用(好吧,全局上下文,不管是什么)

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

  • 如果通过
    new
    操作符调用该函数,则
    将引用新创建的对象
  • 如果对函数的引用是通过对象的属性查找(
    foo.someFunction()
    )获得的,则
    将是对该对象的引用
  • 如果通过函数原型中的
    .call()
    .apply()
    调用函数,则
    将引用这些函数中使用的第一个参数,必要时强制为对象值
  • 如果通过简单的“裸”引用调用函数,则
    将引用全局上下文(
    浏览器中的窗口
    )。edit-Šime Vidas在上面的评论中指出,在严格模式下,这种情况会导致
    (这确实更有意义,并且可以避免在OP中观察到的奇怪)

  • 在Javascript中使用函数有4种方法 其中每一项都会改变
    的内容:

    • 函数调用:this=全局对象(浏览器中的窗口)
    • 方法调用:this=从中调用它的对象
    • 构造函数调用:this=您正在创建的新对象
    • 调用/应用调用:this=您传递的对象
    在您的情况下,
    this==window
    当您直接调用函数(
    outer()
    )时,但如果使用new(
    newouter()
    )调用,则它将是您正在创建的新对象


    基本上,我写的是在函数体内部使用
    这个
    ,如果您打算通过
    new
    ,或者作为一个方法,或者通过
    .call()
    /
    .apply()
    /
    .bind()
    方法之一调用它。通过
    funcName()
    定期调用的函数不应使用
    this
    。此外,如果JavaScript程序在严格模式下运行,并且通过
    funcName()
    调用函数,则
    this
    将是
    未定义的。因此,属性访问(例如,
    this.x
    )会抛出一个引用错误。@jeroenmons,因为对内部的调用是以这样一种方式进行的,即没有其他方式可供调用。确定“this”的行为与任何其他变量不同吗?我的意思是,如果你在外部函数中定义一个var(但在内部函数之外;),并在内部函数中使用它,它会工作的,对吗?是的:
    这实际上不是一个变量。它类似于Smalltalk的“receiver”概念——在这种语言中,它更容易理解,因为函数调用被明确地认为是消息传递,所以“receiver”是您向其发送消息的对象。好的,那么有没有办法确保inner可以访问outer的公共变量x?@hsalama如果您的示例代码根本没有使用
    this
    ,而是将
    x
    y
    作为局部变量,那么它就可以工作了。或者,调用
    internal()
    可以这样做:
    internal.call(this)
    。哈哈,是的,我无耻地从另一个答案中偷走了你的“场景列表”解释:-)