我期待着" taco"函数生成运行时错误,因为我没有使用"这"关键字:
function foo() {
var bar = "baz";
this.taco = function() {
console.log(bar);
};
this.taco();
taco(); // I expected a runtime error here.
}
foo();
然而,它没有。
以下是相同代码的小提琴:http://jsfiddle.net/phillipkregg/gdFxU/226/
JavaScript是否在此使用某种类型的隐式上下文管理?
好奇,谢谢!
答案 0 :(得分:8)
原因是当您调用foo()
时,您将在window
对象的范围内调用它。这意味着在foo()
内,this
的值设置为window
。
因此,this.taco()
实际上是window.taco()
,与taco()
相同。换句话说,taco()
是一个全局函数,因此当taco()
为{{window.taco()
时,它可以将其称为this.taco()
,this
或window
。 1}}。
如果您将taco()
作为这样的新对象,this
设置为foo
的新实例并且不等于window
,那么您将获得预期的运行时错误:
function foo() {
var bar = "baz";
this.taco = function() {
console.log(this);
console.log(bar);
};
this.taco();
taco(); // I expected a runtime error here.
}
var x = new foo();
示例:http://jsfiddle.net/jfriend00/3LkxU/
如果您对this
的价值感到困惑,可以使用这些javascript规则来确定this
的价值:
如果您使用new
调用x = new foo()
之类的函数,则会创建foo
的新实例,并将this
的值设置为该对象在foo()
函数内部,默认情况下从foo()
返回新实例。
如果您通常调用foo()
之类的任何函数,则this
的值将设置为浏览器中window
或javascript更新的全局对象“严格”模式,然后this
将为undefined
。这就是您原始示例中发生的情况。
如果您使用obj.foo()
之类的对象引用调用方法,则this
将设置为obj
对象。
如果您使用.apply()
或.call()
进行函数调用,那么您可以使用{{1的第一个参数来专门控制this
的值设置为什么}或.apply()
。例如:.call()
会调用foo.call(obj)
函数并将foo()
指针设置为this
对象。
如果您没有进行任何函数调用(例如,在全局范围内),那么obj
将是全局对象(浏览器中为this
)或window
严格模式。
与上述所有规则一样,undefined
由调用者如何调用您来控制,而不是如何定义函数/方法。
答案 1 :(得分:2)
原因是foo()中的this
,当它被调用时,将引用一个全局对象。这意味着taco
函数将在全局范围内引入。
要获得所需的功能,请使用new foo()
语法。然后this
将引用一个新对象,taco
属性将被赋予一个新值(函数)。直接拨打taco
会让您收到错误。
答案 2 :(得分:1)
foo(); // equals window.foo() , `this` equals `window` and `this.taco` equals `window.taco` and `window.taco` equals `taco` as it is global
new foo(); //creates a new object. this will give error because here `this.taco` is not `taco`