调用函数和创建函数实例之间的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)
。哈哈,是的,我无耻地从另一个答案中偷走了你的“场景列表”解释:-)